From 57c034f1047eb768ed7287478073570c5c3e7702 Mon Sep 17 00:00:00 2001 From: Yury Melnichek Date: Wed, 14 Dec 2011 19:10:04 +0300 Subject: [PATCH] [search] Correctly handle case, when all names for a language start with the same name. --- search/feature_offset_match.hpp | 31 +++++++++++++++++++++++++++---- search/search_query.cpp | 4 ++-- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/search/feature_offset_match.hpp b/search/feature_offset_match.hpp index cb55b8dcf4..fce07a8425 100644 --- a/search/feature_offset_match.hpp +++ b/search/feature_offset_match.hpp @@ -1,4 +1,5 @@ #pragma once +#include "search_common.hpp" #include "../indexer/search_trie.hpp" #include "../base/string_utils.hpp" #include "../base/base.hpp" @@ -62,9 +63,19 @@ TrieIterator * MoveTrieIteratorToString(TrieIterator const & trieRoot, template void FullMatchInTrie(TrieIterator const & trieRoot, - strings::UniString const & s, + strings::UniChar const * rootPrefix, + size_t rootPrefixSize, + strings::UniString s, F & f) { + if (rootPrefixSize > 0) + { + if (s.size() < rootPrefixSize || + !StartsWith(s.begin(), s.end(), rootPrefix, rootPrefix + rootPrefixSize)) + return; + s = strings::UniString(s.begin() + rootPrefixSize, s.end()); + } + size_t symbolsMatched = 0; scoped_ptr pIter(MoveTrieIteratorToString(trieRoot, s, symbolsMatched)); if (!pIter || symbolsMatched != s.size()) @@ -75,9 +86,19 @@ void FullMatchInTrie(TrieIterator const & trieRoot, template void PrefixMatchInTrie(TrieIterator const & trieRoot, - strings::UniString const & s, + strings::UniChar const * rootPrefix, + size_t rootPrefixSize, + strings::UniString s, F & f) { + if (rootPrefixSize > 0) + { + if (s.size() < rootPrefixSize || + !StartsWith(s.begin(), s.end(), rootPrefix, rootPrefix + rootPrefixSize)) + return; + s = strings::UniString(s.begin() + rootPrefixSize, s.end()); + } + size_t symbolsMatched = 0; scoped_ptr pIter(MoveTrieIteratorToString(trieRoot, s, symbolsMatched)); if (!pIter) @@ -147,6 +168,8 @@ template void MatchFeaturesInTrie(vector > const & tokens, strings::UniString const & prefix, TrieIterator const & trieRoot, + strings::UniChar const * commonPrefix, + size_t commonPrefixSize, unordered_set const * pOffsetsFilter, F & f, size_t resultsNeeded) @@ -157,7 +180,7 @@ void MatchFeaturesInTrie(vector > const & tokens, for (size_t i = 0; i < tokens.size(); ++i) { for (size_t j = 0; j < tokens[i].size(); ++j) - impl::FullMatchInTrie(trieRoot, tokens[i][j], intersecter); + impl::FullMatchInTrie(trieRoot, commonPrefix, commonPrefixSize, tokens[i][j], intersecter); intersecter.NextStep(); } @@ -165,7 +188,7 @@ void MatchFeaturesInTrie(vector > const & tokens, // Match prefix. if (prefix.size() > 0) { - impl::PrefixMatchInTrie(trieRoot, prefix, intersecter); + impl::PrefixMatchInTrie(trieRoot, commonPrefix, commonPrefixSize, prefix, intersecter); intersecter.NextStep(); } diff --git a/search/search_query.cpp b/search/search_query.cpp index bfe735c4bd..9e4bead603 100644 --- a/search/search_query.cpp +++ b/search/search_query.cpp @@ -332,8 +332,7 @@ void Query::SearchFeatures(vector > const & tokens, { TrieIterator::Edge::EdgeStrT const & edge = pTrieRoot->m_edge[i].m_str; ASSERT_GREATER_OR_EQUAL(edge.size(), 1, ()); - // TODO: edge.size() > 1 !! - if (edge.size() == 1 && edge[0] < 128 && langs.count(static_cast(edge[0]))) + if (edge.size() >= 1 && edge[0] < 128 && langs.count(static_cast(edge[0]))) { scoped_ptr pLangRoot(pTrieRoot->GoToEdge(i)); @@ -345,6 +344,7 @@ void Query::SearchFeatures(vector > const & tokens, (h.GetType() == feature::DataHeader::world) ? "" : mwmLock.GetCountryName()); MatchFeaturesInTrie(tokens, m_prefix, *pLangRoot, + edge.size() == 1 ? NULL : &edge[1], edge.size() - 1, &m_offsetsInViewport[mwmId], f, m_results.max_size() * 10); LOG(LDEBUG, ("Lang:",