diff --git a/generator/search_index_builder.cpp b/generator/search_index_builder.cpp index da8b88b32b..2a047c2aeb 100644 --- a/generator/search_index_builder.cpp +++ b/generator/search_index_builder.cpp @@ -286,6 +286,8 @@ public: if (skipIndex.SkipAlways(types)) return; + if (skipIndex.SkipSpecialNames(types, f.GetName(StringUtf8Multilang::kDefaultCode))) + return; auto const isCountryOrState = [](auto types) { diff --git a/search/search_integration_tests/smoke_test.cpp b/search/search_integration_tests/smoke_test.cpp index 0cdaabdca0..8127d47302 100644 --- a/search/search_integration_tests/smoke_test.cpp +++ b/search/search_integration_tests/smoke_test.cpp @@ -148,19 +148,39 @@ UNIT_CLASS_TEST(SmokeTest, TypesSkipperTest) { TypesSkipper skipper; - base::StringIL const arr[] = { - {"barrier", "block"}, - {"barrier", "toll_booth"}, - {"entrance"} - }; - auto const & cl = classif(); - for (auto const & path : arr) - { - TypesHolder types; - types.Add(cl.GetTypeByPath(path)); - TEST(!skipper.SkipAlways(types), (path)); + { + base::StringIL const arr[] = {{"entrance"}}; + TypesHolder types; + for (auto const & path : arr) + types.Add(cl.GetTypeByPath(path)); + + TEST(!skipper.SkipAlways(types), ()); + TEST(!skipper.SkipSpecialNames(types, "ETH"), ()); + TEST(skipper.SkipSpecialNames(types, "2"), ()); + } + + { + base::StringIL const arr[] = {{"building"}}; + TypesHolder types; + for (auto const & path : arr) + types.Add(cl.GetTypeByPath(path)); + + TEST(!skipper.SkipAlways(types), ()); + TEST(!skipper.SkipSpecialNames(types, "3"), ()); + skipper.SkipEmptyNameTypes(types); + TEST(types.Empty(), ()); + } + + { + base::StringIL const arr[] = {{"building"}, {"entrance"}}; + TypesHolder types; + for (auto const & path : arr) + types.Add(cl.GetTypeByPath(path)); + + TEST(!skipper.SkipAlways(types), ()); + TEST(!skipper.SkipSpecialNames(types, "4"), ()); skipper.SkipEmptyNameTypes(types); TEST_EQUAL(types.Size(), 1, ()); } @@ -218,8 +238,6 @@ UNIT_CLASS_TEST(SmokeTest, CategoriesTest) invisibleTypes.insert(cl.GetTypeByPath(tags)); base::StringIL const notSupportedTags[] = { - // Not visible because excluded by TypesSkipper. - {"building", "address"}, // Not visible for country scale range. {"place", "continent"}, {"place", "region"} diff --git a/search/types_skipper.cpp b/search/types_skipper.cpp index dc02105028..df2ca26725 100644 --- a/search/types_skipper.cpp +++ b/search/types_skipper.cpp @@ -16,27 +16,37 @@ TypesSkipper::TypesSkipper() { Classificator const & c = classif(); - StringIL const typesLengthOne[] = {{"building"}, {"highway"}, {"landuse"}, {"natural"}, - {"office"}, {"waterway"}, {"area:highway"}}; - - for (auto const & e : typesLengthOne) + StringIL const arrSkipEmptyName1[] = { + {"building"}, {"highway"}, {"landuse"}, {"natural"}, {"office"}, {"waterway"}, {"area:highway"} + }; + for (auto const & e : arrSkipEmptyName1) m_skipIfEmptyName[0].push_back(c.GetTypeByPath(e)); - StringIL const typesLengthTwo[] = {{"man_made", "chimney"}, - {"place", "country"}, - {"place", "state"}, - {"place", "county"}, - {"place", "region"}, - {"place", "city"}, - {"place", "town"}, - {"place", "suburb"}, - {"place", "neighbourhood"}, - {"place", "square"}}; + StringIL const arrSkipEmptyName2[] = { + {"man_made", "chimney"}, - for (auto const & e : typesLengthTwo) + /// @todo Skip all nameless places? + {"place", "country"}, + {"place", "state"}, + {"place", "county"}, + {"place", "region"}, + {"place", "city"}, + {"place", "town"}, + {"place", "suburb"}, + {"place", "neighbourhood"}, + {"place", "square"} + }; + for (auto const & e : arrSkipEmptyName2) m_skipIfEmptyName[1].push_back(c.GetTypeByPath(e)); m_skipAlways[0].push_back(c.GetTypeByPath({"isoline"})); + + // Do not index "entrance" only features. + StringIL const arrSkipSpecialNames1[] = { + {"entrance"}, {"wheelchair"} + }; + for (auto const & e : arrSkipSpecialNames1) + m_skipSpecialNames[0].push_back(c.GetTypeByPath(e)); } void TypesSkipper::SkipEmptyNameTypes(feature::TypesHolder & types) const @@ -64,10 +74,6 @@ bool TypesSkipper::SkipAlways(feature::TypesHolder const & types) const { for (auto type : types) { - ftype::TruncValue(type, 2); - if (HasType(m_skipAlways[1], type)) - return true; - ftype::TruncValue(type, 1); if (HasType(m_skipAlways[0], type)) return true; @@ -75,6 +81,24 @@ bool TypesSkipper::SkipAlways(feature::TypesHolder const & types) const return false; } +bool TypesSkipper::SkipSpecialNames(feature::TypesHolder const & types, std::string_view defName) const +{ + // Since we assign ref tag into name for entrances, this is a crutch to avoid indexing + // these refs (entrance numbers for CIS countries). + /// @todo Move refs into metadata? + + uint32_t dummy; + if (!strings::to_uint(defName, dummy)) + return false; + + for (auto type : types) + { + if (!HasType(m_skipSpecialNames[0], type)) + return false; + } + return true; +} + // static bool TypesSkipper::HasType(Cont const & v, uint32_t t) { diff --git a/search/types_skipper.hpp b/search/types_skipper.hpp index cf9b4f4a44..08e060cba2 100644 --- a/search/types_skipper.hpp +++ b/search/types_skipper.hpp @@ -20,6 +20,8 @@ public: // Useful for mixed features, sponsored objects. bool SkipAlways(feature::TypesHolder const & types) const; + bool SkipSpecialNames(feature::TypesHolder const & types, std::string_view defName) const; + private: using Cont = buffer_vector; @@ -27,6 +29,7 @@ private: // Array index (0, 1) means type level for checking (1, 2). Cont m_skipIfEmptyName[2]; - Cont m_skipAlways[2]; + Cont m_skipAlways[1]; + Cont m_skipSpecialNames[1]; }; } // namespace search