diff --git a/search/query.cpp b/search/query.cpp index 4a5068e8db..207cdd5350 100644 --- a/search/query.cpp +++ b/search/query.cpp @@ -234,36 +234,40 @@ void Query::Search(function const & f) if (m_bTerminate) return; - if (m_pTrieRoot) + int const scale = scales::GetScaleLevel(m_viewport); + + if (scale > scales::GetUpperWorldScale()) { - search::MatchAgainstTrie(*this, *m_pTrieRoot, *m_pFeatures); + // First - make features matching for viewport in current country. + try + { + FeatureProcessor featureProcessor(*this); + /// @todo Tune depth scale search (1 is no enough) + m_pIndex->ForEachInRect(featureProcessor, m_viewport, min(scales::GetUpperScale(), scale + 1)); + } + catch (FeatureProcessor::StopException &) + { + LOG(LDEBUG, ("FeatureProcessor::StopException")); + } } if (m_bTerminate) return; FlushResults(f); - if (m_resultsRemaining == 0 || m_queryText.empty()) + if (m_resultsRemaining == 0) { f(Result(string(), string())); // Send last search result marker. return; } - // Feature matching. - if (m_pTrieRoot == 0) - { - try - { - /// @todo Tune depth scale search (1 is no enough) - int const scale = min(scales::GetUpperScale(), scales::GetScaleLevel(m_viewport) + 1); + if (m_bTerminate) + return; - FeatureProcessor featureProcessor(*this); - m_pIndex->ForEachInRect(featureProcessor, m_viewport, scale); - } - catch (FeatureProcessor::StopException &) - { - LOG(LDEBUG, ("FeatureProcessor::StopException")); - } + if (m_pTrieRoot) + { + // Make features matching in world trie. + search::MatchAgainstTrie(*this, *m_pTrieRoot, *m_pFeatures); } if (m_bTerminate) diff --git a/search/search_trie_matching.cpp b/search/search_trie_matching.cpp index 376f9ca5a3..069ae8e99d 100644 --- a/search/search_trie_matching.cpp +++ b/search/search_trie_matching.cpp @@ -12,6 +12,18 @@ #include "../std/vector.hpp" +namespace +{ + template + size_t CalcEqualLength(SrcIterT b, SrcIterT e, CompIterT bC, CompIterT eC) + { + size_t count = 0; + while ((b != e) && (bC != eC) && (*b++ == *bC++)) + ++count; + return count; + } +} + void search::MatchAgainstTrie(search::impl::Query & query, search::TrieIterator & trieRoot, FeaturesVector const & featuresVector) { @@ -26,19 +38,25 @@ void search::MatchAgainstTrie(search::impl::Query & query, search::TrieIterator while (symbolsMatched < szQuery) { bool bMatched = false; + for (size_t i = 0; i < pIter->m_edge.size(); ++i) { size_t const szEdge = pIter->m_edge[i].m_str.size(); - if (szEdge + symbolsMatched <= szQuery && - equal(pIter->m_edge[i].m_str.begin(), pIter->m_edge[i].m_str.end(), - queryS.begin() + symbolsMatched)) + + size_t const count = CalcEqualLength(pIter->m_edge[i].m_str.begin(), + pIter->m_edge[i].m_str.end(), + queryS.begin() + symbolsMatched, + queryS.end()); + + if ((count > 0) && (count == szEdge || szQuery == count + symbolsMatched)) { scoped_ptr(pIter->GoToEdge(i)).swap(pIter); - symbolsMatched += szEdge; + symbolsMatched += count; bMatched = true; break; } } + if (!bMatched) return; }