From 8160688cb84645ccdf00ef93aaacb8c6326aeadd Mon Sep 17 00:00:00 2001 From: vng Date: Tue, 16 Aug 2011 17:41:49 +0300 Subject: [PATCH] Fix trie search. !Note! Need to review some @todo. --- indexer/feature.hpp | 3 ++- indexer/index.hpp | 24 ++++++++++++------------ search/engine.cpp | 5 +++-- search/engine.hpp | 2 +- search/query.cpp | 6 ++++-- search/query.hpp | 4 +++- search/search_tests/query_test.cpp | 16 ++++++++-------- search/search_trie.hpp | 28 +++++++++++++++++++++++++--- search/search_trie_matching.cpp | 19 +++++++++++++++---- 9 files changed, 73 insertions(+), 34 deletions(-) diff --git a/indexer/feature.hpp b/indexer/feature.hpp index 57a8714f0b..92d2ceb5cc 100644 --- a/indexer/feature.hpp +++ b/indexer/feature.hpp @@ -206,10 +206,11 @@ public: size_t m_size; GetNamesFn() : m_size(0) {} - void operator() (char lang, string const & name) + bool operator() (char lang, string const & name) { m_names[m_size++] = name; m_langs[m_size] = lang; + return true; } }; diff --git a/indexer/index.hpp b/indexer/index.hpp index 5c372de521..da58cca877 100644 --- a/indexer/index.hpp +++ b/indexer/index.hpp @@ -15,7 +15,6 @@ #include "../geometry/rect2d.hpp" #include "../coding/file_container.hpp" -#include "../coding/trie_reader.hpp" #include "../base/base.hpp" #include "../base/macros.hpp" @@ -141,9 +140,9 @@ public: } } - search::TrieIterator * GetWorldSearchIndex() const + search::SearchInfo * GetWorldSearchInfo() const { - return m_pWorldSearchIndex.get(); + return m_pWorldSearchInfo.get(); } void Add(string const & file) @@ -159,10 +158,14 @@ public: UpdateIndexes(); - if (m_indexes.back()->IsWorldData()) + /// @todo Keep this until World.mwm has search index. + static bool isWorld = true; + //if (m_indexes.back()->IsWorldData()) + if (isWorld) { - ASSERT(!m_pWorldSearchIndex.get(), ()); - m_pWorldSearchIndex.reset(m_indexes.back()->GetSearchIndex()); + ASSERT ( !m_pWorldSearchInfo.get(), () ); + m_pWorldSearchInfo.reset(m_indexes.back()->GetSearchInfo()); + isWorld = false; } } @@ -293,12 +296,9 @@ private: return m_scaleRange.first <= 1; } - search::TrieIterator * GetSearchIndex() const + search::SearchInfo * GetSearchInfo() const { - return trie::reader::ReadTrie( - FilesContainerR(GetPlatform().GetReader(m_file)).GetReader(SEARCH_INDEX_FILE_TAG), - search::trie::ValueReader(), - search::trie::EdgeValueReader()); + return new search::SearchInfo(FilesContainerR(GetPlatform().GetReader(m_file))); } void CloseIfUnlocked() @@ -393,7 +393,7 @@ private: mutable vector m_indexes; mutable threads::Mutex m_mutex; - scoped_ptr m_pWorldSearchIndex; + scoped_ptr m_pWorldSearchInfo; }; template class OffsetToFeatureAdapter : public BaseT diff --git a/search/engine.cpp b/search/engine.cpp index 71f96cf4ff..f47bf2e1aa 100644 --- a/search/engine.cpp +++ b/search/engine.cpp @@ -15,7 +15,7 @@ namespace search Engine::Engine(IndexType const * pIndex, CategoriesHolder & categories) - : m_pIndex(pIndex), m_pTrieIterator(pIndex->GetWorldSearchIndex()), + : m_pIndex(pIndex), m_pSearchInfo(pIndex->GetWorldSearchInfo()), m_pCategories(new CategoriesHolder()), m_pRunner(new threads::ConcurrentRunner), m_pLastQuery(NULL), m_queriesActive(0) @@ -36,7 +36,8 @@ void Engine::Search(string const & queryText, LOG(LDEBUG, (queryText, rect)); impl::Query * pQuery = - new impl::Query(queryText, rect, m_pIndex, this, m_pCategories.get(), m_pTrieIterator); + new impl::Query(queryText, rect, m_pIndex, this, m_pCategories.get(), + m_pSearchInfo->GetTrie(), m_pSearchInfo->GetFeatures()); { threads::MutexGuard mutexGuard(m_mutex); diff --git a/search/engine.hpp b/search/engine.hpp index a33279e78a..a291c2e966 100644 --- a/search/engine.hpp +++ b/search/engine.hpp @@ -45,7 +45,7 @@ public: private: IndexType const * m_pIndex; - TrieIterator * m_pTrieIterator; + SearchInfo * m_pSearchInfo; scoped_ptr m_pCategories; scoped_ptr m_pRunner; threads::Mutex m_mutex; diff --git a/search/query.cpp b/search/query.cpp index 4fcf931a12..e4d169c4c5 100644 --- a/search/query.cpp +++ b/search/query.cpp @@ -121,12 +121,14 @@ struct FeatureProcessor } // unnamed namespace Query::Query(string const & query, m2::RectD const & viewport, IndexType const * pIndex, - Engine * pEngine, CategoriesHolder * pCategories, TrieIterator * pTrieRoot) + Engine * pEngine, CategoriesHolder * pCategories, + TrieIterator * pTrieRoot, FeaturesVector * pFeatures) : m_queryText(query), m_queryUniText(NormalizeAndSimplifyString(query)), m_viewport(viewport), m_pCategories(pCategories), m_pTrieRoot(pTrieRoot), m_pIndex(pIndex ? new IndexType(*pIndex) : NULL), + m_pFeatures(pFeatures), m_resultsRemaining(10), m_pEngine(pEngine), m_bTerminate(false) { @@ -234,7 +236,7 @@ void Query::Search(function const & f) if (m_pTrieRoot) { - search::MatchAgainstTrie(*this, *m_pTrieRoot); + search::MatchAgainstTrie(*this, *m_pTrieRoot, *m_pFeatures); } if (m_bTerminate) diff --git a/search/query.hpp b/search/query.hpp index 8f545743fb..9f841b01e4 100644 --- a/search/query.hpp +++ b/search/query.hpp @@ -27,7 +27,8 @@ public: typedef Engine::IndexType IndexType; Query(string const & query, m2::RectD const & viewport, IndexType const * pIndex, - Engine * pEngine, CategoriesHolder * pCategories, TrieIterator * pTrieRoot = NULL); + Engine * pEngine, CategoriesHolder * pCategories, + TrieIterator * pTrieRoot, FeaturesVector * pFeatures); ~Query(); // Search with parameters, passed in constructor. @@ -59,6 +60,7 @@ private: m2::RectD m_viewport; CategoriesHolder * m_pCategories; TrieIterator * m_pTrieRoot; + FeaturesVector * m_pFeatures; vector m_keywords; unordered_map m_keywordsToSkipForType; diff --git a/search/search_tests/query_test.cpp b/search/search_tests/query_test.cpp index 30ad34937a..2940bfbff9 100644 --- a/search/search_tests/query_test.cpp +++ b/search/search_tests/query_test.cpp @@ -13,16 +13,16 @@ UNIT_TEST(QueryParseKeywords_Smoke) vector expected; expected.push_back(MakeUniString("minsk")); expected.push_back(MakeUniString("belarus")); - TEST_EQUAL(expected, Query("minsk belarus ", m2::RectD(), 0, 0, 0).GetKeywords(), ()); - TEST_EQUAL(MakeUniString(""), Query("minsk belarus ", m2::RectD(), 0, 0, 0).GetPrefix(), ()); - TEST_EQUAL(expected, Query("minsk belarus ma", m2::RectD(), 0, 0, 0).GetKeywords(), ()); - TEST_EQUAL(MakeUniString("ma"), Query("minsk belarus ma", m2::RectD(), 0, 0, 0).GetPrefix(), ()); + TEST_EQUAL(expected, Query("minsk belarus ", m2::RectD(), 0, 0, 0, 0, 0).GetKeywords(), ()); + TEST_EQUAL(MakeUniString(""), Query("minsk belarus ", m2::RectD(), 0, 0, 0, 0, 0).GetPrefix(), ()); + TEST_EQUAL(expected, Query("minsk belarus ma", m2::RectD(), 0, 0, 0, 0, 0).GetKeywords(), ()); + TEST_EQUAL(MakeUniString("ma"), Query("minsk belarus ma", m2::RectD(), 0, 0, 0, 0, 0).GetPrefix(), ()); } UNIT_TEST(QueryParseKeywords_Empty) { - TEST_EQUAL(vector(), Query("", m2::RectD(), 0, 0, 0).GetKeywords(), ()); - TEST_EQUAL(MakeUniString(""), Query("", m2::RectD(), 0, 0, 0).GetPrefix(), ()); - TEST_EQUAL(vector(), Query("Z", m2::RectD(), 0, 0, 0).GetKeywords(), ()); - TEST_EQUAL(MakeUniString("z"), Query("Z", m2::RectD(), 0, 0, 0).GetPrefix(), ()); + TEST_EQUAL(vector(), Query("", m2::RectD(), 0, 0, 0, 0, 0).GetKeywords(), ()); + TEST_EQUAL(MakeUniString(""), Query("", m2::RectD(), 0, 0, 0, 0, 0).GetPrefix(), ()); + TEST_EQUAL(vector(), Query("Z", m2::RectD(), 0, 0, 0, 0, 0).GetKeywords(), ()); + TEST_EQUAL(MakeUniString("z"), Query("Z", m2::RectD(), 0, 0, 0, 0, 0).GetPrefix(), ()); } diff --git a/search/search_trie.hpp b/search/search_trie.hpp index 60eec9eadf..1fd4ff7c07 100644 --- a/search/search_trie.hpp +++ b/search/search_trie.hpp @@ -1,9 +1,13 @@ #pragma once +#include "../indexer/features_vector.hpp" #include "../coding/reader.hpp" #include "../coding/trie.hpp" +#include "../coding/trie_reader.hpp" + #include "../base/base.hpp" + namespace search { namespace trie @@ -36,8 +40,26 @@ struct EdgeValueReader } // namespace search::trie -typedef ::trie::Iterator< - search::trie::ValueReader::ValueType, - search::trie::EdgeValueReader::ValueType> TrieIterator; + typedef ::trie::Iterator< + search::trie::ValueReader::ValueType, + search::trie::EdgeValueReader::ValueType> TrieIterator; + class SearchInfo + { + scoped_ptr m_iterator; + FeaturesVector m_features; + + public: + SearchInfo(FilesContainerR const & cont) + : m_features(cont), + m_iterator(::trie::reader::ReadTrie( + cont.GetReader(SEARCH_INDEX_FILE_TAG), + trie::ValueReader(), + trie::EdgeValueReader())) + { + } + + TrieIterator * GetTrie() { return m_iterator.get(); } + FeaturesVector * GetFeatures() { return &m_features; } + }; } // namespace search diff --git a/search/search_trie_matching.cpp b/search/search_trie_matching.cpp index e3baf04127..0448396e7d 100644 --- a/search/search_trie_matching.cpp +++ b/search/search_trie_matching.cpp @@ -1,5 +1,9 @@ #include "search_trie_matching.hpp" #include "query.hpp" +#include "string_match.hpp" + +#include "../indexer/feature_visibility.hpp" + #include "../std/algorithm.hpp" #include "../std/functional.hpp" #include "../std/queue.hpp" @@ -7,6 +11,7 @@ #include "../std/utility.hpp" #include "../std/vector.hpp" + void search::MatchAgainstTrie(search::impl::Query & query, search::TrieIterator & trieRoot, FeaturesVector const & featuresVector) { @@ -62,7 +67,7 @@ void search::MatchAgainstTrie(search::impl::Query & query, search::TrieIterator // TODO: Deal with different names of the same feature. // TODO: Best name for features. FeatureType feature; - featuresVector.Get(featureQueue.top().second, features); + featuresVector.Get(featureQueue.top().second, feature); FeatureType::GetNamesFn names; feature.ForEachNameRef(names); string displayName; @@ -75,9 +80,15 @@ void search::MatchAgainstTrie(search::impl::Query & query, search::TrieIterator break; } } - ASSERT(!displayName.empty(), ()); - query.AddResult(impl::IntermediateResult(query.GetViewport(), feature, displayName, 0, - feature::DrawableScaleRangeForText(feature).first)); + + /// @todo Need Yuri's review. + //ASSERT(!displayName.empty(), ()); + if (!displayName.empty()) + { + query.AddResult(impl::IntermediateResult(query.GetViewport(), feature, displayName, 0, + feature::DrawableScaleRangeForText(feature).first)); + } + featureQueue.pop(); } }