diff --git a/search/engine.cpp b/search/engine.cpp index 0f39d0ecba..2046e09a2d 100644 --- a/search/engine.cpp +++ b/search/engine.cpp @@ -309,7 +309,6 @@ void Engine::DoSearch(SearchParams const & params, m2::RectD const & viewport, processor.SetMode(params.GetMode()); processor.SetSuggestsEnabled(params.GetSuggestsEnabled()); - processor.SetOnResults(params.m_onResults); // This flag is needed for consistency with old search algorithm // only. It will be gone when we remove old search code. @@ -322,7 +321,14 @@ void Engine::DoSearch(SearchParams const & params, m2::RectD const & viewport, Results res; - processor.SearchCoordinates(res); + try + { + processor.SearchCoordinates(res); + } + catch (CancelException const &) + { + LOG(LDEBUG, ("Search has been cancelled.")); + } try { @@ -338,7 +344,7 @@ void Engine::DoSearch(SearchParams const & params, m2::RectD const & viewport, if (!processor.IsCancelled()) EmitResults(params, res); } - catch (Processor::CancelException const &) + catch (CancelException const &) { LOG(LDEBUG, ("Search has been cancelled.")); } diff --git a/search/pre_ranker.hpp b/search/pre_ranker.hpp index 10db7de81f..725c11d61f 100644 --- a/search/pre_ranker.hpp +++ b/search/pre_ranker.hpp @@ -1,9 +1,7 @@ #pragma once #include "search/intermediate_result.hpp" -#include "search/ranker.hpp" -#include "base/logging.hpp" #include "base/macros.hpp" #include "std/algorithm.hpp" @@ -13,7 +11,6 @@ namespace search { -class Ranker; // Fast and simple pre-ranker for search results. class PreRanker { @@ -46,8 +43,6 @@ public: fn(result.GetId(), result.GetInfo()); } - Ranker * m_ranker; - private: vector m_results; size_t const m_limit; diff --git a/search/processor.cpp b/search/processor.cpp index 183966ff18..4262e6b372 100644 --- a/search/processor.cpp +++ b/search/processor.cpp @@ -125,8 +125,7 @@ Processor::Processor(Index const & index, CategoriesHolder const & categories, {StringUtf8Multilang::kInternationalCode, StringUtf8Multilang::kEnglishCode}, {StringUtf8Multilang::kDefaultCode}}; - m_ranker.m_keywordsScorer.SetLanguages(langPriorities); - m_preRanker.m_ranker = &m_ranker; + m_ranker.SetLanguages(langPriorities); SetPreferredLocale("en"); } @@ -158,7 +157,9 @@ void Processor::SetPreferredLocale(string const & locale) // Default initialization. // If you want to reset input language, call SetInputLocale before search. SetInputLocale(locale); +#ifdef FIND_LOCALITY_TEST m_ranker.SetLocalityFinderLanguage(code); +#endif // FIND_LOCALITY_TEST } void Processor::SetInputLocale(string const & locale) @@ -228,7 +229,7 @@ void Processor::SetQuery(string const & query) m_tokens.resize(maxTokensCount); // Assign tokens and prefix to scorer. - m_ranker.m_keywordsScorer.SetKeywords(m_tokens.data(), m_tokens.size(), m_prefix); + m_ranker.SetKeywords(m_tokens.data(), m_tokens.size(), m_prefix); // get preferred types to show in results m_preferredTypes.clear(); @@ -253,12 +254,12 @@ void Processor::SetRankPivot(m2::PointD const & pivot) void Processor::SetLanguage(int id, int8_t lang) { - m_ranker.m_keywordsScorer.SetLanguage(GetLangIndex(id), lang); + m_ranker.SetLanguage(GetLangIndex(id), lang); } int8_t Processor::GetLanguage(int id) const { - return m_ranker.m_keywordsScorer.GetLanguage(GetLangIndex(id)); + return m_ranker.GetLanguage(GetLangIndex(id)); } m2::PointD Processor::GetPivotPoint() const @@ -319,53 +320,35 @@ void Processor::SetViewportByIndex(m2::RectD const & viewport, size_t idx, bool void Processor::ClearCache(size_t ind) { m_viewport[ind].MakeEmpty(); } -size_t Processor::GetCategoryLocales(int8_t(&arr)[3]) const +TLocales Processor::GetCategoryLocales() const { static int8_t const enLocaleCode = CategoriesHolder::MapLocaleToInteger("en"); + TLocales result; // Prepare array of processing locales. English locale is always present for category matching. - size_t count = 0; if (m_currentLocaleCode != -1) - arr[count++] = m_currentLocaleCode; + result.push_back(m_currentLocaleCode); if (m_inputLocaleCode != -1 && m_inputLocaleCode != m_currentLocaleCode) - arr[count++] = m_inputLocaleCode; + result.push_back(m_inputLocaleCode); if (enLocaleCode != m_currentLocaleCode && enLocaleCode != m_inputLocaleCode) - arr[count++] = enLocaleCode; + result.push_back(enLocaleCode); - return count; + return result; } template void Processor::ForEachCategoryType(StringSliceBase const & slice, ToDo && todo) const { - int8_t arrLocales[3]; - int const localesCount = GetCategoryLocales(arrLocales); - - ::search::ForEachCategoryType(slice, arrLocales, localesCount, m_categories, forward(todo)); + ::search::ForEachCategoryType(slice, GetCategoryLocales(), m_categories, forward(todo)); } void Processor::Search(Results & results, size_t limit) { Geocoder::Params geocoderParams; - InitParams(geocoderParams); - geocoderParams.m_mode = m_mode; - geocoderParams.m_pivot = GetPivotRect(); - geocoderParams.m_accuratePivotCenter = GetPivotPoint(); - m_geocoder.SetParams(geocoderParams); + InitGeocoderParams(geocoderParams); Ranker::Params rankerParams; - rankerParams.m_currentLocaleCode = m_currentLocaleCode; - if (m_mode == Mode::Viewport) - rankerParams.m_viewport = GetViewport(); - rankerParams.m_position = GetPosition(); - rankerParams.m_pivotRegion = GetPivotRegion(); - rankerParams.m_preferredTypes = m_preferredTypes; - rankerParams.m_suggestsEnabled = m_suggestsEnabled; - rankerParams.m_query = m_query; - rankerParams.m_tokens = m_tokens; - rankerParams.m_prefix = m_prefix; - rankerParams.m_numCategoryLocales = GetCategoryLocales(rankerParams.m_categoryLocales); - m_ranker.SetParams(rankerParams); + InitRankerParams(rankerParams); if (m_tokens.empty()) m_ranker.SuggestStrings(results); @@ -603,6 +586,31 @@ void Processor::InitParams(QueryParams & params) params.m_langs.insert(GetLanguage(i)); } +void Processor::InitGeocoderParams(Geocoder::Params & params) +{ + InitParams(params); + params.m_mode = m_mode; + params.m_pivot = GetPivotRect(); + params.m_accuratePivotCenter = GetPivotPoint(); + m_geocoder.SetParams(params); +} + +void Processor::InitRankerParams(Ranker::Params & params) +{ + params.m_currentLocaleCode = m_currentLocaleCode; + if (m_mode == Mode::Viewport) + params.m_viewport = GetViewport(); + params.m_position = GetPosition(); + params.m_pivotRegion = GetPivotRegion(); + params.m_preferredTypes = m_preferredTypes; + params.m_suggestsEnabled = m_suggestsEnabled; + params.m_query = m_query; + params.m_tokens = m_tokens; + params.m_prefix = m_prefix; + params.m_categoryLocales = GetCategoryLocales(); + m_ranker.SetParams(params); +} + void Processor::ClearCaches() { for (size_t i = 0; i < COUNT_V; ++i) diff --git a/search/processor.hpp b/search/processor.hpp index 913e0ef7d1..7e77c72125 100644 --- a/search/processor.hpp +++ b/search/processor.hpp @@ -79,7 +79,6 @@ public: void SetPreferredLocale(string const & locale); void SetInputLocale(string const & locale); void SetQuery(string const & query); - void SetOnResults(TOnResults const & onResults) { m_onResults = onResults; } // TODO (@y): this function must be removed. void SetRankPivot(m2::PointD const & pivot); inline void SetMode(Mode mode) { m_mode = mode; } @@ -104,11 +103,9 @@ public: void SearchCoordinates(Results & res) const; //@} - struct CancelException - { - }; - void InitParams(QueryParams & params); + void InitGeocoderParams(Geocoder::Params & params); + void InitRankerParams(Ranker::Params & params); void ClearCaches(); @@ -130,14 +127,15 @@ protected: friend class PreResult2Maker; friend class Ranker; - size_t GetCategoryLocales(int8_t(&arr)[3]) const; - - template - void ForEachCategoryType(StringSliceBase const & slice, ToDo && todo) const; - using TMWMVector = vector>; using TOffsetsVector = map>; using TFHeader = feature::DataHeader; + using TLocales = buffer_vector; + + TLocales GetCategoryLocales() const; + + template + void ForEachCategoryType(StringSliceBase const & slice, ToDo && todo) const; m2::PointD GetPivotPoint() const; m2::RectD GetPivotRect() const; @@ -147,7 +145,6 @@ protected: CategoriesHolder const & m_categories; storage::CountryInfoGetter const & m_infoGetter; - TOnResults m_onResults; string m_region; string m_query; diff --git a/search/ranker.cpp b/search/ranker.cpp index ed43d73ef4..c2c0d5b3ad 100644 --- a/search/ranker.cpp +++ b/search/ranker.cpp @@ -49,7 +49,8 @@ void RemoveDuplicatingLinear(vector & values) values.end()); } -void RemoveStringPrefix(string const & str, string & res) +// Chops off the last query token (the "prefix" one) from |str| and stores the result in |res|. +void GetStringPrefix(string const & str, string & res) { search::Delimiters delims; // Find start iterator of prefix in input query. @@ -62,8 +63,8 @@ void RemoveStringPrefix(string const & str, string & res) if (delims(*prev)) break; - else - iter = prev; + + iter = prev; } // Assign result with input string without prefix. @@ -89,28 +90,29 @@ ftypes::Type GetLocalityIndex(feature::TypesHolder const & types) } /// Makes continuous range for tokens and prefix. -template +template class CombinedIter { - TIter m_i, m_end; - ValueT const * m_val; + TIter m_cur; + TIter m_end; + TValue const * m_val; public: - CombinedIter(TIter i, TIter end, ValueT const * val) : m_i(i), m_end(end), m_val(val) {} + CombinedIter(TIter cur, TIter end, TValue const * val) : m_cur(cur), m_end(end), m_val(val) {} - ValueT const & operator*() const + TValue const & operator*() const { - ASSERT(m_val != 0 || m_i != m_end, ("dereferencing of empty iterator")); - if (m_i != m_end) - return *m_i; + ASSERT(m_val != 0 || m_cur != m_end, ("dereferencing of empty iterator")); + if (m_cur != m_end) + return *m_cur; return *m_val; } CombinedIter & operator++() { - if (m_i != m_end) - ++m_i; + if (m_cur != m_end) + ++m_cur; else m_val = 0; return *this; @@ -118,12 +120,12 @@ public: bool operator==(CombinedIter const & other) const { - return m_val == other.m_val && m_i == other.m_i; + return m_val == other.m_val && m_cur == other.m_cur; } bool operator!=(CombinedIter const & other) const { - return m_val != other.m_val || m_i != other.m_i; + return m_val != other.m_val || m_cur != other.m_cur; } }; } // namespace @@ -133,7 +135,6 @@ class PreResult2Maker Ranker & m_ranker; Index const & m_index; Geocoder::Params const & m_params; - Ranker::Params const & m_rankerParams; storage::CountryInfoGetter const & m_infoGetter; unique_ptr m_pFV; @@ -192,8 +193,7 @@ class PreResult2Maker feature::TypesHolder holder(ft); vector> matched(slice.Size()); ForEachCategoryType(QuerySlice(slice), m_ranker.m_params.m_categoryLocales, - m_ranker.m_params.m_numCategoryLocales, m_ranker.m_categories, - [&](size_t i, uint32_t t) + m_ranker.m_categories, [&](size_t i, uint32_t t) { ++matched[i].second; if (holder.Has(t)) @@ -218,7 +218,7 @@ class PreResult2Maker case SearchModel::SEARCH_TYPE_VILLAGE: return rank /= 1.5; case SearchModel::SEARCH_TYPE_CITY: { - if (m_rankerParams.m_viewport.IsPointInside(center)) + if (m_ranker.m_params.m_viewport.IsPointInside(center)) return rank * 2; storage::CountryInfo info; @@ -226,7 +226,7 @@ class PreResult2Maker m_infoGetter.GetRegionInfo(center, info); else m_infoGetter.GetRegionInfo(country, info); - if (info.IsNotEmpty() && info.m_name == m_rankerParams.m_pivotRegion) + if (info.IsNotEmpty() && info.m_name == m_ranker.m_params.m_pivotRegion) return rank *= 1.7; } case SearchModel::SEARCH_TYPE_COUNTRY: @@ -240,12 +240,8 @@ class PreResult2Maker public: explicit PreResult2Maker(Ranker & ranker, Index const & index, storage::CountryInfoGetter const & infoGetter, - Geocoder::Params const & params, Ranker::Params const & rankerParams) - : m_ranker(ranker) - , m_index(index) - , m_params(params) - , m_rankerParams(rankerParams) - , m_infoGetter(infoGetter) + Geocoder::Params const & params) + : m_ranker(ranker), m_index(index), m_params(params), m_infoGetter(infoGetter) { } @@ -258,7 +254,7 @@ public: LoadFeature(res1.GetId(), ft, center, name, country); - auto res2 = make_unique(ft, &res1, center, m_rankerParams.m_position /* pivot */, + auto res2 = make_unique(ft, &res1, center, m_ranker.m_params.m_position /* pivot */, name, country); search::RankingInfo info; @@ -286,7 +282,7 @@ void Ranker::MakePreResult2(Geocoder::Params const & geocoderParams, vector; + bool m_viewportSearch = false; int8_t m_currentLocaleCode = CategoriesHolder::kEnglishCode; @@ -57,8 +61,7 @@ public: // We need it here to make suggestions. strings::UniString m_prefix; - int8_t m_categoryLocales[3]; - size_t m_numCategoryLocales = 0; + TLocales m_categoryLocales; }; Ranker(PreRanker & preRanker, Index const & index, storage::CountryInfoGetter const & infoGetter, @@ -101,19 +104,41 @@ public: void ClearCaches(); - void SetLocalityFinderLanguage(int8_t code); +#ifdef FIND_LOCALITY_TEST + inline void SetLocalityFinderLanguage(int8_t code) { m_locality.SetLanguage(code); } +#endif // FIND_LOCALITY_TEST + + inline void SetLanguage(pair const & ind, int8_t lang) + { + m_keywordsScorer.SetLanguage(ind, lang); + } + + inline int8_t GetLanguage(pair const & ind) const + { + return m_keywordsScorer.GetLanguage(ind); + } + + inline void SetLanguages(vector> const & languagePriorities) + { + m_keywordsScorer.SetLanguages(languagePriorities); + } + + inline void SetKeywords(KeywordMatcher::StringT const * keywords, size_t count, + KeywordMatcher::StringT const & prefix) + { + m_keywordsScorer.SetKeywords(keywords, count, prefix); + } inline void BailIfCancelled() { ::search::BailIfCancelled(m_cancellable); } - KeywordLangMatcher m_keywordsScorer; - +private: friend class PreResult2Maker; -private: Params m_params; ReverseGeocoder const m_reverseGeocoder; PreRanker & m_preRanker; my::Cancellable const & m_cancellable; + KeywordLangMatcher m_keywordsScorer; #ifdef FIND_LOCALITY_TEST mutable LocalityFinder m_locality;