diff --git a/indexer/categories_holder.cpp b/indexer/categories_holder.cpp index 4cd965ef1a..2f7baf0c43 100644 --- a/indexer/categories_holder.cpp +++ b/indexer/categories_holder.cpp @@ -141,8 +141,9 @@ void ProcessCategory(string const & line, vector & groups, vector && reader) ReaderStreamBuf buffer(move(reader)); istream s(&buffer); LoadFromStream(s); + +#if defined(DEBUG) + for (auto const & entry : kLocaleMapping) + ASSERT_LESS_OR_EQUAL(entry.m_code, kMaxSupportedLocaleIndex, ()); +#endif } void CategoriesHolder::AddCategory(Category & cat, vector & types) diff --git a/indexer/categories_holder.hpp b/indexer/categories_holder.hpp index d46fd47615..40f34bc597 100644 --- a/indexer/categories_holder.hpp +++ b/indexer/categories_holder.hpp @@ -63,8 +63,9 @@ private: GroupTranslations m_groupTranslations; public: - static int8_t const kEnglishCode; - static int8_t const kUnsupportedLocaleCode; + static int8_t constexpr kEnglishCode = 1; + static int8_t constexpr kUnsupportedLocaleCode = -1; + static uint8_t constexpr kMaxSupportedLocaleIndex = 30; static vector const kLocaleMapping; // List of languages that are currently disabled in the application diff --git a/search/processor.cpp b/search/processor.cpp index f2363e203b..35b4da3089 100644 --- a/search/processor.cpp +++ b/search/processor.cpp @@ -397,12 +397,11 @@ Locales Processor::GetCategoryLocales() const Locales result; // Prepare array of processing locales. English locale is always present for category matching. + result.Insert(static_cast(enLocaleCode)); if (m_currentLocaleCode != -1) - result.push_back(m_currentLocaleCode); - if (m_inputLocaleCode != -1 && m_inputLocaleCode != m_currentLocaleCode) - result.push_back(m_inputLocaleCode); - if (enLocaleCode != m_currentLocaleCode && enLocaleCode != m_inputLocaleCode) - result.push_back(enLocaleCode); + result.Insert(static_cast(m_currentLocaleCode)); + if (m_inputLocaleCode != -1) + result.Insert(static_cast(m_inputLocaleCode)); return result; } diff --git a/search/processor.hpp b/search/processor.hpp index 7da64228bf..96310054a8 100644 --- a/search/processor.hpp +++ b/search/processor.hpp @@ -12,6 +12,7 @@ #include "search/search_trie.hpp" #include "search/suggest.hpp" #include "search/token_slice.hpp" +#include "search/utils.hpp" #include "indexer/ftypes_matcher.hpp" #include "indexer/index.hpp" @@ -132,9 +133,8 @@ protected: using TMWMVector = vector>; using TOffsetsVector = map>; using TFHeader = feature::DataHeader; - using TLocales = buffer_vector; - TLocales GetCategoryLocales() const; + Locales GetCategoryLocales() const; template void ForEachCategoryType(StringSliceBase const & slice, ToDo && toDo) const; diff --git a/search/ranker.hpp b/search/ranker.hpp index 6e220824df..867f247d17 100644 --- a/search/ranker.hpp +++ b/search/ranker.hpp @@ -10,6 +10,7 @@ #include "search/reverse_geocoder.hpp" #include "search/search_params.hpp" #include "search/suggest.hpp" +#include "search/utils.hpp" #include "indexer/categories_holder.hpp" #include "indexer/feature_decl.hpp" @@ -43,8 +44,6 @@ class Ranker public: struct Params { - using TLocales = buffer_vector; - int8_t m_currentLocaleCode = CategoriesHolder::kEnglishCode; m2::RectD m_viewport; m2::PointD m_position; @@ -65,7 +64,7 @@ public: // filtering of indentical search results. double m_minDistanceOnMapBetweenResults = 0.0; - TLocales m_categoryLocales; + Locales m_categoryLocales; size_t m_limit = 0; }; diff --git a/search/utils.hpp b/search/utils.hpp index e152d842c8..564c9b919c 100644 --- a/search/utils.hpp +++ b/search/utils.hpp @@ -8,6 +8,7 @@ #include "base/buffer_vector.hpp" #include "base/levenshtein_dfa.hpp" +#include "base/small_set.hpp" #include "base/stl_helpers.hpp" #include "base/string_utils.hpp" @@ -20,6 +21,8 @@ namespace search { +using Locales = base::SafeSmallSet; + // todo(@m, @y). Unite with the similar function in search/feature_offset_match.hpp. template bool MatchInTrie(TrieIt const & trieStartIt, DFA const & dfa, ToDo && toDo) @@ -64,8 +67,6 @@ bool MatchInTrie(TrieIt const & trieStartIt, DFA const & dfa, ToDo && toDo) return found; } -using Locales = buffer_vector; - size_t GetMaxErrorsForToken(strings::UniString const & token); strings::LevenshteinDFA BuildLevenshteinDFA(strings::UniString const & s); @@ -103,8 +104,6 @@ void ForEachCategoryTypeFuzzy(StringSliceBase const & slice, Locales const & loc auto const & trie = categories.GetNameToTypesTrie(); auto const & trieRootIt = trie.GetRootIterator(); - vector sortedLocales(locales.begin(), locales.end()); - my::SortUnique(sortedLocales); for (size_t i = 0; i < slice.Size(); ++i) { @@ -115,7 +114,7 @@ void ForEachCategoryTypeFuzzy(StringSliceBase const & slice, Locales const & loc strings::LevenshteinDFA const dfa(BuildLevenshteinDFA(token)); trieRootIt.ForEachMove([&](Trie::Char const & c, Trie::Iterator const & trieStartIt) { - if (std::binary_search(sortedLocales.begin(), sortedLocales.end(), static_cast(c))) + if (locales.Contains(static_cast(c))) MatchInTrie(trieStartIt, dfa, std::bind(todo, i, std::placeholders::_1)); }); } @@ -136,7 +135,7 @@ bool IsCategorialRequest(QuerySliceOnRawStrings const & slice, Locales const bool found = false; auto token = slice.Get(0); catHolder.ForEachName([&](CategoriesHolder::Category::Name const & categorySynonym) { - if (std::find(locales.begin(), locales.end(), categorySynonym.m_locale) == locales.end()) + if (!locales.Contains(static_cast(categorySynonym.m_locale))) return; if (token != strings::MakeUniString(categorySynonym.m_name))