diff --git a/search/geocoder.cpp b/search/geocoder.cpp index 4286646c6a..0900d58dc7 100644 --- a/search/geocoder.cpp +++ b/search/geocoder.cpp @@ -158,7 +158,7 @@ public: FeatureType ft; if (!m_context.GetFeature(featureId, ft)) return; - for (auto const & lang : m_params.m_langs) + for (auto const & lang : m_params.GetLangs()) { string name; if (ft.GetName(lang, name)) @@ -180,16 +180,9 @@ void JoinQueryTokens(QueryParams const & params, size_t curToken, size_t endToke ASSERT_LESS_OR_EQUAL(curToken, endToken, ()); for (size_t i = curToken; i < endToken; ++i) { - if (i < params.m_tokens.size()) - { - res.append(params.m_tokens[i].front()); - } - else - { - CHECK_EQUAL(i, params.m_tokens.size(), ()); - CHECK(!params.m_prefixTokens.empty(), ()); - res.append(params.m_prefixTokens.front()); - } + auto const & syms = params.GetTokens(i); + CHECK(!syms.empty(), ("Empty synonyms for token:", i)); + res.append(syms.front()); if (i + 1 != endToken) res.append(sep); @@ -381,13 +374,19 @@ void Geocoder::SetParams(Params const & params) m_params = params; // Filter stop words. - if (m_params.m_tokens.size() > 1) + if (m_params.GetNumTokens() > 1) { - for (size_t i = 0; i < m_params.m_tokens.size();) + for (size_t i = 0; i < m_params.GetNumTokens();) { - auto & tokens = m_params.m_tokens[i]; - my::EraseIf(tokens, &IsStopWord); - if (tokens.empty()) + if (m_params.IsPrefixToken(i)) + { + ++i; + continue; + } + + auto & syms = m_params.GetTokens(i); + my::EraseIf(syms, &IsStopWord); + if (syms.empty()) m_params.RemoveToken(i); else ++i; @@ -406,53 +405,47 @@ void Geocoder::SetParams(Params const & params) ASSERT(!synonyms.empty(), ()); if (IsStreetSynonym(synonyms.front())) - m_params.m_typeIndices[i].clear(); + m_params.GetTypeIndices(i).clear(); } - m_tokenRequests.resize(m_params.m_tokens.size()); - for (size_t i = 0; i < m_params.m_tokens.size(); ++i) + m_tokenRequests.clear(); + m_prefixTokenRequest.Clear(); + for (size_t i = 0; i < m_params.GetNumTokens(); ++i) { - auto & request = m_tokenRequests[i]; - request.Clear(); - for (auto const & name : m_params.m_tokens[i]) + if (!m_params.IsPrefixToken(i)) { - // Here and below, we use LevenshteinDFAs for fuzzy - // matching. But due to performance reasons, we assume that the - // first letter is always correct. - if (!IsHashtagged(name)) - request.m_names.emplace_back(name, 1 /* prefixCharsToKeep */, GetMaxErrorsForToken(name)); - else - request.m_names.emplace_back(name, 0 /* maxErrors */); - } - for (auto const & index : m_params.m_typeIndices[i]) - request.m_categories.emplace_back(FeatureTypeToString(index)); - request.m_langs = m_params.m_langs; - } - - if (m_params.LastTokenIsPrefix()) - { - auto & request = m_prefixTokenRequest; - request.Clear(); - for (auto const & name : m_params.m_prefixTokens) - { - if (!IsHashtagged(name)) + m_tokenRequests.emplace_back(); + auto & request = m_tokenRequests.back(); + for (auto const & name : m_params.GetTokens(i)) { + // Here and below, we use LevenshteinDFAs for fuzzy + // matching. But due to performance reasons, we assume that the + // first letter is always correct. + request.m_names.emplace_back(name, 1 /* prefixCharsToKeep */, GetMaxErrorsForToken(name)); + } + for (auto const & index : m_params.GetTypeIndices(i)) + request.m_categories.emplace_back(FeatureTypeToString(index)); + request.m_langs = m_params.GetLangs(); + } + else + { + auto & request = m_prefixTokenRequest; + for (auto const & name : m_params.GetTokens(i)) + { + LOG(LINFO, ("Adding prefix name:", name)); request.m_names.emplace_back( LevenshteinDFA(name, 1 /* prefixCharsToKeep */, GetMaxErrorsForToken(name))); } - else + for (auto const & index : m_params.GetTypeIndices(i)) { - request.m_names.emplace_back(LevenshteinDFA(name, 0 /* maxErrors */)); + LOG(LINFO, ("Adding category:", FeatureTypeToString(index))); + request.m_categories.emplace_back(FeatureTypeToString(index)); } + request.m_langs = m_params.GetLangs(); } - for (auto const & index : m_params.m_typeIndices.back()) - request.m_categories.emplace_back(FeatureTypeToString(index)); - request.m_langs = m_params.m_langs; } - LOG(LDEBUG, ("Tokens =", m_params.m_tokens)); - LOG(LDEBUG, ("Prefix tokens =", m_params.m_prefixTokens)); - LOG(LDEBUG, ("Languages =", m_params.m_langs)); + LOG(LDEBUG, (DebugPrint(static_cast(m_params)))); } void Geocoder::GoEverywhere() @@ -526,6 +519,7 @@ void Geocoder::GoImpl(vector> & infos, bool inViewport) InitBaseContext(ctx); FillLocalitiesTable(ctx); } + m_context.reset(); } } @@ -629,9 +623,16 @@ void Geocoder::InitBaseContext(BaseContext & ctx) for (size_t i = 0; i < ctx.m_features.size(); ++i) { if (m_params.IsPrefixToken(i)) + { + LOG(LINFO, ("Token is prefix.")); ctx.m_features[i] = RetrieveAddressFeatures(*m_context, m_cancellable, m_prefixTokenRequest); + } else + { + LOG(LINFO, ("Token is full.")); ctx.m_features[i] = RetrieveAddressFeatures(*m_context, m_cancellable, m_tokenRequests[i]); + } + LOG(LINFO, ("For i-th token:", i, ctx.m_features[i].PopCount())); } ctx.m_hotelsFilter = m_hotelsFilter.MakeScopedFilter(*m_context, m_params.m_hotelsFilter); } @@ -646,7 +647,8 @@ void Geocoder::InitLayer(SearchModel::SearchType type, size_t startToken, size_t JoinQueryTokens(m_params, layer.m_startToken, layer.m_endToken, kUniSpace /* sep */, layer.m_subQuery); - layer.m_lastTokenIsPrefix = (layer.m_endToken > m_params.m_tokens.size()); + layer.m_lastTokenIsPrefix = + layer.m_startToken < layer.m_endToken && m_params.IsPrefixToken(layer.m_endToken - 1); } void Geocoder::FillLocalityCandidates(BaseContext const & ctx, CBV const & filter, @@ -1400,8 +1402,8 @@ CBV Geocoder::RetrieveGeometryFeatures(MwmContext const & context, m2::RectD con { switch (id) { - case RECT_ID_PIVOT: return m_pivotRectsCache.Get(context, rect, m_params.m_scale); - case RECT_ID_LOCALITY: return m_localityRectsCache.Get(context, rect, m_params.m_scale); + case RECT_ID_PIVOT: return m_pivotRectsCache.Get(context, rect, m_params.GetScale()); + case RECT_ID_LOCALITY: return m_localityRectsCache.Get(context, rect, m_params.GetScale()); case RECT_ID_COUNT: ASSERT(false, ("Invalid RectId.")); return CBV(); } } diff --git a/search/geocoder.hpp b/search/geocoder.hpp index f46af7d19b..6aa412594d 100644 --- a/search/geocoder.hpp +++ b/search/geocoder.hpp @@ -184,7 +184,7 @@ private: template using TLocalitiesCache = map, vector>; - QueryParams::TSynonymsVector const & GetTokens(size_t i) const; + QueryParams::Synonyms const & GetTokens(size_t i) const; // Creates a cache of posting lists corresponding to features in m_context // for each token and saves it to m_addressFeatures. diff --git a/search/locality_scorer.hpp b/search/locality_scorer.hpp index d0b51eaf68..cd59a50deb 100644 --- a/search/locality_scorer.hpp +++ b/search/locality_scorer.hpp @@ -8,7 +8,7 @@ namespace search { -struct QueryParams; +class QueryParams; class LocalityScorer { diff --git a/search/processor.cpp b/search/processor.cpp index c551b02285..fd8c40eb7e 100644 --- a/search/processor.cpp +++ b/search/processor.cpp @@ -613,28 +613,17 @@ int GetOldTypeFromIndex(size_t index) void Processor::InitParams(QueryParams & params) { - params.Clear(); - - if (!m_prefix.empty()) - params.m_prefixTokens.push_back(m_prefix); - - size_t const tokensCount = m_tokens.size(); - - // Add normal tokens. - params.m_tokens.resize(tokensCount); - for (size_t i = 0; i < tokensCount; ++i) - params.m_tokens[i].push_back(m_tokens[i]); - - params.m_typeIndices.resize(tokensCount + (m_prefix.empty() ? 0 : 1)); - for (auto & indices : params.m_typeIndices) - indices.clear(); + if (m_prefix.empty()) + params.Init(m_tokens.begin(), m_tokens.end()); + else + params.InitWithPrefix(m_tokens.begin(), m_tokens.end(), m_prefix); // Add names of categories (and synonyms). Classificator const & c = classif(); auto addSyms = [&](size_t i, uint32_t t) { uint32_t const index = c.GetIndexForType(t); - params.m_typeIndices[i].push_back(index); + params.GetTypeIndices(i).push_back(index); // v2-version MWM has raw classificator types in search index prefix, so // do the hack: add synonyms for old convention if needed. @@ -644,22 +633,15 @@ void Processor::InitParams(QueryParams & params) if (type >= 0) { ASSERT(type == 70 || type > 4000, (type)); - params.m_typeIndices[i].push_back(static_cast(type)); + params.GetTypeIndices(i).push_back(static_cast(type)); } } }; ForEachCategoryType(QuerySliceOnRawStrings(m_tokens, m_prefix), addSyms); - for (auto & tokens : params.m_tokens) - { - if (tokens.size() > 1 && IsHashtagged(tokens[0])) - tokens.erase(tokens.begin()); - } - if (params.m_prefixTokens.size() > 1 && IsHashtagged(params.m_prefixTokens[0])) - params.m_prefixTokens.erase(params.m_prefixTokens.begin()); - + auto & langs = params.GetLangs(); for (int i = 0; i < LANG_COUNT; ++i) - params.m_langs.insert(GetLanguage(i)); + langs.insert(GetLanguage(i)); } void Processor::InitGeocoder(Geocoder::Params & params) @@ -688,7 +670,7 @@ void Processor::InitPreRanker(Geocoder::Params const & geocoderParams) params.m_minDistanceOnMapBetweenResults = m_minDistanceOnMapBetweenResults; } params.m_accuratePivotCenter = GetPivotPoint(); - params.m_scale = geocoderParams.m_scale; + params.m_scale = geocoderParams.GetScale(); m_preRanker.Init(params); } diff --git a/search/processor.hpp b/search/processor.hpp index 7ca2ea7552..5e784954fd 100644 --- a/search/processor.hpp +++ b/search/processor.hpp @@ -50,17 +50,15 @@ namespace search { struct Locality; struct Region; -struct QueryParams; -class ReverseGeocoder; -class Geocoder; -class Ranker; -// todo(@m) Merge with Ranker. -class PreResult2Maker; - -class FeatureLoader; class DoFindLocality; +class FeatureLoader; +class Geocoder; class HouseCompFactory; +class PreResult2Maker; // todo(@m) merge with Ranker +class QueryParams; +class Ranker; +class ReverseGeocoder; class Processor : public my::Cancellable { diff --git a/search/query_params.cpp b/search/query_params.cpp index 7e65aedf08..d404996671 100644 --- a/search/query_params.cpp +++ b/search/query_params.cpp @@ -14,7 +14,7 @@ class DoAddStreetSynonyms public: DoAddStreetSynonyms(QueryParams & params) : m_params(params) {} - void operator()(QueryParams::TString const & s, size_t i) + void operator()(QueryParams::String const & s, size_t i) { if (s.size() > 2) return; @@ -40,15 +40,7 @@ public: } private: - QueryParams::TSynonymsVector & GetSyms(size_t i) const - { - size_t const count = m_params.m_tokens.size(); - if (i < count) - return m_params.m_tokens[i]; - ASSERT_EQUAL(i, count, ()); - return m_params.m_prefixTokens; - } - + QueryParams::Synonyms & GetSyms(size_t i) const { return m_params.GetTokens(i); } void AddSym(size_t i, string const & sym) { GetSyms(i).push_back(strings::MakeUniString(sym)); } QueryParams & m_params; @@ -64,10 +56,18 @@ void QueryParams::Clear() m_scale = scales::GetUpperScale(); } -bool QueryParams::IsCategorySynonym(size_t i) const +bool QueryParams::IsCategorySynonym(size_t i) const { return !GetTypeIndices(i).empty(); } + +QueryParams::TypeIndices & QueryParams::GetTypeIndices(size_t i) { ASSERT_LESS(i, GetNumTokens(), ()); - return !m_typeIndices[i].empty(); + return m_typeIndices[i]; +} + +QueryParams::TypeIndices const & QueryParams::GetTypeIndices(size_t i) const +{ + ASSERT_LESS(i, GetNumTokens(), ()); + return m_typeIndices[i]; } bool QueryParams::IsPrefixToken(size_t i) const @@ -76,13 +76,13 @@ bool QueryParams::IsPrefixToken(size_t i) const return i == m_tokens.size(); } -QueryParams::TSynonymsVector const & QueryParams::GetTokens(size_t i) const +QueryParams::Synonyms const & QueryParams::GetTokens(size_t i) const { ASSERT_LESS(i, GetNumTokens(), ()); return i < m_tokens.size() ? m_tokens[i] : m_prefixTokens; } -QueryParams::TSynonymsVector & QueryParams::GetTokens(size_t i) +QueryParams::Synonyms & QueryParams::GetTokens(size_t i) { ASSERT_LESS(i, GetNumTokens(), ()); return i < m_tokens.size() ? m_tokens[i] : m_prefixTokens; @@ -125,7 +125,9 @@ string DebugPrint(search::QueryParams const & params) { ostringstream os; os << "QueryParams [ m_tokens=" << DebugPrint(params.m_tokens) - << ", m_prefixTokens=" << DebugPrint(params.m_prefixTokens) << "]"; + << ", m_prefixTokens=" << DebugPrint(params.m_prefixTokens) + << ", m_typeIndices=" << ::DebugPrint(params.m_typeIndices) + << ", m_langs=" << ::DebugPrint(params.m_langs) << " ]"; return os.str(); } } // namespace search diff --git a/search/query_params.hpp b/search/query_params.hpp index f4a8836a0a..e879fe9ed5 100644 --- a/search/query_params.hpp +++ b/search/query_params.hpp @@ -11,14 +11,35 @@ namespace search { -struct QueryParams +class QueryParams { - using TString = strings::UniString; - using TSynonymsVector = vector; - using TLangsSet = unordered_set; +public: + using String = strings::UniString; + using Synonyms = vector; + using TypeIndices = vector; + using Langs = unordered_set; QueryParams() = default; + template + void Init(It tokenBegin, It tokenEnd) + { + Clear(); + for (; tokenBegin != tokenEnd; ++tokenBegin) + m_tokens.push_back({*tokenBegin}); + m_typeIndices.resize(GetNumTokens()); + } + + template + void InitWithPrefix(It tokenBegin, It tokenEnd, String const & prefix) + { + Clear(); + for (; tokenBegin != tokenEnd; ++tokenBegin) + m_tokens.push_back({*tokenBegin}); + m_prefixTokens.push_back(prefix); + m_typeIndices.resize(GetNumTokens()); + } + inline size_t GetNumTokens() const { return m_prefixTokens.empty() ? m_tokens.size() : m_tokens.size() + 1; @@ -27,14 +48,15 @@ struct QueryParams inline bool LastTokenIsPrefix() const { return !m_prefixTokens.empty(); } inline bool IsEmpty() const { return GetNumTokens() == 0; } - inline bool IsLangExist(int8_t lang) const { return m_langs.count(lang) != 0; } - void Clear(); bool IsCategorySynonym(size_t i) const; + TypeIndices & GetTypeIndices(size_t i); + TypeIndices const & GetTypeIndices(size_t i) const; + bool IsPrefixToken(size_t i) const; - TSynonymsVector const & GetTokens(size_t i) const; - TSynonymsVector & GetTokens(size_t i); + Synonyms const & GetTokens(size_t i) const; + Synonyms & GetTokens(size_t i); // Returns true if all tokens in [start, end) range have integral // synonyms. @@ -42,13 +64,20 @@ struct QueryParams void RemoveToken(size_t i); - vector m_tokens; - TSynonymsVector m_prefixTokens; - vector> m_typeIndices; + inline Langs & GetLangs() { return m_langs; } + inline Langs const & GetLangs() const { return m_langs; } + inline bool IsLangExist(int8_t lang) const { return m_langs.count(lang) != 0; } - TLangsSet m_langs; + inline int GetScale() const { return m_scale; } + +private: + friend string DebugPrint(search::QueryParams const & params); + + vector m_tokens; + Synonyms m_prefixTokens; + vector m_typeIndices; + + Langs m_langs; int m_scale = scales::GetUpperScale(); }; - -string DebugPrint(search::QueryParams const & params); } // namespace search diff --git a/search/ranker.cpp b/search/ranker.cpp index 9c2b5d2c58..f4aaf6a54d 100644 --- a/search/ranker.cpp +++ b/search/ranker.cpp @@ -182,7 +182,7 @@ class PreResult2Maker TokenSlice slice(m_params, preInfo.m_startToken, preInfo.m_endToken); TokenSliceNoCategories sliceNoCategories(m_params, preInfo.m_startToken, preInfo.m_endToken); - for (auto const & lang : m_params.m_langs) + for (auto const & lang : m_params.GetLangs()) { string name; if (!ft.GetName(lang, name)) diff --git a/search/ranking_utils.hpp b/search/ranking_utils.hpp index d247bc4ef9..5dd9496360 100644 --- a/search/ranking_utils.hpp +++ b/search/ranking_utils.hpp @@ -16,7 +16,7 @@ namespace search { -struct QueryParams; +class QueryParams; namespace impl { diff --git a/search/search_integration_tests/processor_test.cpp b/search/search_integration_tests/processor_test.cpp index 0affd84bf2..13c000fbf5 100644 --- a/search/search_integration_tests/processor_test.cpp +++ b/search/search_integration_tests/processor_test.cpp @@ -18,6 +18,7 @@ #include "geometry/rect2d.hpp" #include "base/assert.hpp" +#include "base/macros.hpp" #include "base/math.hpp" #include "std/shared_ptr.hpp" @@ -531,10 +532,12 @@ UNIT_CLASS_TEST(ProcessorTest, TestPostcodes) my::Cancellable cancellable; QueryParams params; - params.m_tokens.emplace_back(); - params.m_tokens.back().push_back(strings::MakeUniString("141702")); + { + strings::UniString const tokens[] = {strings::MakeUniString("141702")}; + params.Init(tokens, tokens + ARRAY_SIZE(tokens)); + } auto features = RetrievePostcodeFeatures(context, cancellable, - TokenSlice(params, 0, params.m_tokens.size())); + TokenSlice(params, 0, params.GetNumTokens())); TEST_EQUAL(1, features->PopCount(), ()); uint64_t index = 0; @@ -657,25 +660,6 @@ UNIT_CLASS_TEST(ProcessorTest, TestCategories) } } - { - TRules const rules = {ExactMatch(wonderlandId, nonameAtm), ExactMatch(wonderlandId, namedAtm)}; - - auto request = MakeRequest("#atm"); - - TEST(MatchResults(rules, request->Results()), ()); - for (auto const & result : request->Results()) - { - auto const & info = result.GetRankingInfo(); - - // Token with a hashtag should not participate in name-score - // calculations. - TEST_EQUAL(NAME_SCORE_ZERO, info.m_nameScore, (result)); - } - } - - // Tests that inexistent hashtagged categories do not crash. - TEST(ResultsMatch("#void-", TRules{}), ()); - TEST(ResultsMatch("wifi", {ExactMatch(wonderlandId, cafe)}), ()); TEST(ResultsMatch("wi-fi", {ExactMatch(wonderlandId, cafe)}), ()); TEST(ResultsMatch("wai-fai", TRules{}), ()); diff --git a/search/search_tests/locality_scorer_test.cpp b/search/search_tests/locality_scorer_test.cpp index 7223c73431..17306796bd 100644 --- a/search/search_tests/locality_scorer_test.cpp +++ b/search/search_tests/locality_scorer_test.cpp @@ -22,20 +22,20 @@ namespace { void InitParams(string const & query, bool lastTokenIsPrefix, QueryParams & params) { - params.m_tokens.clear(); - params.m_prefixTokens.clear(); + params.Clear(); vector tokens; - Delimiters delims; SplitUniString(NormalizeAndSimplifyString(query), MakeBackInsertFunctor(tokens), delims); - for (auto const & token : tokens) - params.m_tokens.push_back({token}); + if (lastTokenIsPrefix) { - ASSERT(!params.m_tokens.empty(), ()); - params.m_prefixTokens = params.m_tokens.back(); - params.m_tokens.pop_back(); + CHECK(!tokens.empty(), ()); + params.InitWithPrefix(tokens.begin(), tokens.end() - 1, tokens.back()); + } + else + { + params.Init(tokens.begin(), tokens.end()); } } @@ -47,9 +47,7 @@ void AddLocality(string const & name, uint32_t featureId, QueryParams & params, Delimiters delims; SplitUniString(NormalizeAndSimplifyString(name), MakeInsertFunctor(tokens), delims); - size_t numTokens = params.m_tokens.size(); - if (!params.m_prefixTokens.empty()) - ++numTokens; + size_t numTokens = params.GetNumTokens(); for (size_t startToken = 0; startToken != numTokens; ++startToken) { @@ -59,8 +57,7 @@ void AddLocality(string const & name, uint32_t featureId, QueryParams & params, for (size_t i = startToken; i != endToken && matches; ++i) { UniString const & queryToken = params.GetTokens(i).front(); - bool const isPrefix = (i == params.m_tokens.size()); - if (isPrefix) + if (params.IsPrefixToken(i)) { matches = any_of(tokens.begin(), tokens.end(), [&queryToken](UniString const & token) { diff --git a/search/search_tests/ranking_tests.cpp b/search/search_tests/ranking_tests.cpp index 7c1df97352..e313ebbee5 100644 --- a/search/search_tests/ranking_tests.cpp +++ b/search/search_tests/ranking_tests.cpp @@ -7,6 +7,7 @@ #include "indexer/search_delimiters.hpp" #include "indexer/search_string_utils.hpp" +#include "base/stl_add.hpp" #include "base/string_utils.hpp" #include "std/cstdint.hpp" @@ -21,17 +22,20 @@ NameScore GetScore(string const & name, string const & query, size_t startToken, { search::Delimiters delims; QueryParams params; - auto addToken = [¶ms](UniString const & token) - { - params.m_tokens.push_back({token}); - }; - SplitUniString(NormalizeAndSimplifyString(query), addToken, delims); - if (!params.m_tokens.empty() && !delims(strings::LastUniChar(query))) + vector tokens; + SplitUniString(NormalizeAndSimplifyString(query), MakeBackInsertFunctor(tokens), delims); + + if (!query.empty() && !delims(strings::LastUniChar(query))) { - params.m_prefixTokens.swap(params.m_tokens.back()); - params.m_tokens.pop_back(); + CHECK(!tokens.empty(), ()); + params.InitWithPrefix(tokens.begin(), tokens.end() - 1, tokens.back()); } + else + { + params.Init(tokens.begin(), tokens.end()); + } + return GetNameScore(name, TokenSlice(params, startToken, endToken)); } diff --git a/search/streets_matcher.cpp b/search/streets_matcher.cpp index dfd524f327..e28088abce 100644 --- a/search/streets_matcher.cpp +++ b/search/streets_matcher.cpp @@ -155,7 +155,7 @@ void StreetsMatcher::FindStreets(BaseContext const & ctx, FeaturesFilter const & ++curToken) { auto const & token = params.GetTokens(curToken).front(); - bool const isPrefix = curToken >= params.m_tokens.size(); + bool const isPrefix = params.IsPrefixToken(curToken); if (house_numbers::LooksLikeHouseNumber(token, isPrefix)) emit(); diff --git a/search/streets_matcher.hpp b/search/streets_matcher.hpp index 7918380774..d362c0dd9a 100644 --- a/search/streets_matcher.hpp +++ b/search/streets_matcher.hpp @@ -8,7 +8,7 @@ namespace search { class FeaturesFilter; -struct QueryParams; +class QueryParams; class StreetsMatcher { diff --git a/search/token_slice.cpp b/search/token_slice.cpp index 33ab649498..bff3dc3fd5 100644 --- a/search/token_slice.cpp +++ b/search/token_slice.cpp @@ -22,6 +22,7 @@ string SliceToString(string const & name, TSlice const & slice) } } // namespace +// TokenSlice -------------------------------------------------------------------------------------- TokenSlice::TokenSlice(QueryParams const & params, size_t startToken, size_t endToken) : m_params(params), m_offset(startToken), m_size(endToken - startToken) { @@ -31,17 +32,10 @@ TokenSlice::TokenSlice(QueryParams const & params, size_t startToken, size_t end bool TokenSlice::IsPrefix(size_t i) const { ASSERT_LESS(i, Size(), ()); - return m_offset + i == m_params.m_tokens.size(); -} - -bool TokenSlice::IsLast(size_t i) const -{ - ASSERT_LESS(i, Size(), ()); - if (m_params.m_prefixTokens.empty()) - return m_offset + i + 1 == m_params.m_tokens.size(); - return m_offset + i == m_params.m_tokens.size(); + return m_params.IsPrefixToken(m_offset + i); } +// TokenSliceNoCategories -------------------------------------------------------------------------- TokenSliceNoCategories::TokenSliceNoCategories(QueryParams const & params, size_t startToken, size_t endToken) : m_params(params) diff --git a/search/token_slice.hpp b/search/token_slice.hpp index 87da032ce9..999f542370 100644 --- a/search/token_slice.hpp +++ b/search/token_slice.hpp @@ -17,7 +17,7 @@ class TokenSlice public: TokenSlice(QueryParams const & params, size_t startToken, size_t endToken); - inline QueryParams::TSynonymsVector const & Get(size_t i) const + inline QueryParams::Synonyms const & Get(size_t i) const { ASSERT_LESS(i, Size(), ()); return m_params.GetTokens(m_offset + i); @@ -31,10 +31,6 @@ public: // (prefix) token. bool IsPrefix(size_t i) const; - // Returns true if the |i|-th token in the slice is the last - // (regardless - full or not) token in the query. - bool IsLast(size_t i) const; - private: QueryParams const & m_params; size_t const m_offset; @@ -46,7 +42,7 @@ class TokenSliceNoCategories public: TokenSliceNoCategories(QueryParams const & params, size_t startToken, size_t endToken); - inline QueryParams::TSynonymsVector const & Get(size_t i) const + inline QueryParams::Synonyms const & Get(size_t i) const { ASSERT_LESS(i, Size(), ()); return m_params.GetTokens(m_indexes[i]); @@ -55,12 +51,7 @@ public: inline size_t Size() const { return m_indexes.size(); } inline bool Empty() const { return Size() == 0; } - - inline bool IsPrefix(size_t i) const - { - ASSERT_LESS(i, Size(), ()); - return m_indexes[i] == m_params.m_tokens.size(); - } + inline bool IsPrefix(size_t i) const { return m_params.IsPrefixToken(m_indexes[i]); } private: QueryParams const & m_params; @@ -73,24 +64,24 @@ public: QuerySlice(TokenSlice const & slice) : m_slice(slice) {} // QuerySlice overrides: - QueryParams::TString const & Get(size_t i) const override { return m_slice.Get(i).front(); } + QueryParams::String const & Get(size_t i) const override { return m_slice.Get(i).front(); } size_t Size() const override { return m_slice.Size(); } private: TokenSlice const m_slice; }; -template +template class QuerySliceOnRawStrings : public StringSliceBase { public: - QuerySliceOnRawStrings(TCont const & tokens, TString const & prefix) + QuerySliceOnRawStrings(Cont const & tokens, TString const & prefix) : m_tokens(tokens), m_prefix(prefix) { } // QuerySlice overrides: - QueryParams::TString const & Get(size_t i) const override + QueryParams::String const & Get(size_t i) const override { ASSERT_LESS(i, Size(), ()); return i == m_tokens.size() ? m_prefix : m_tokens[i]; @@ -99,8 +90,8 @@ public: size_t Size() const override { return m_tokens.size() + (m_prefix.empty() ? 0 : 1); } private: - TCont const & m_tokens; - TString const & m_prefix; + Cont const & m_tokens; + QueryParams::String const & m_prefix; }; string DebugPrint(TokenSlice const & slice); diff --git a/search/utils.hpp b/search/utils.hpp index d1c8e3ea48..2a1ae8402f 100644 --- a/search/utils.hpp +++ b/search/utils.hpp @@ -11,22 +11,13 @@ namespace search { using TLocales = buffer_vector; -inline bool IsHashtagged(strings::UniString const & s) { return !s.empty() && s[0] == '#'; } - -inline strings::UniString RemoveHashtag(strings::UniString const & s) -{ - if (IsHashtagged(s)) - return strings::UniString(s.begin() + 1, s.end()); - return s; -} - template void ForEachCategoryType(StringSliceBase const & slice, TLocales const & locales, CategoriesHolder const & categories, ToDo && todo) { for (size_t i = 0; i < slice.Size(); ++i) { - auto token = RemoveHashtag(slice.Get(i)); + auto token = slice.Get(i); for (size_t j = 0; j < locales.size(); ++j) categories.ForEachTypeByName(locales[j], token, bind(todo, i, _1));