From 172ae59ca509838ffe0b20f2643942d78664fc03 Mon Sep 17 00:00:00 2001 From: Alex Zolotarev Date: Wed, 27 Jan 2016 17:35:07 +0300 Subject: [PATCH] =?UTF-8?q?[editor]=20Integration=20with=20search=20by=20f?= =?UTF-8?q?eature=E2=80=99s=20name.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- search/retrieval.cpp | 103 ++++++++++++++++++++++++++++++++++------- search/retrieval.hpp | 6 ++- search/v2/geocoder.cpp | 18 +++---- 3 files changed, 99 insertions(+), 28 deletions(-) diff --git a/search/retrieval.cpp b/search/retrieval.cpp index 8b0314d956..8a32619333 100644 --- a/search/retrieval.cpp +++ b/search/retrieval.cpp @@ -5,11 +5,13 @@ #include "interval_set.hpp" #include "mwm_traits.hpp" #include "search_index_values.hpp" +#include "search_string_utils.hpp" #include "search_trie.hpp" #include "indexer/feature.hpp" #include "indexer/feature_algo.hpp" #include "indexer/index.hpp" +#include "indexer/osm_editor.hpp" #include "indexer/scales.hpp" #include "indexer/trie_reader.hpp" @@ -25,6 +27,8 @@ #include "std/cmath.hpp" #include "std/limits.hpp" +using osm::Editor; + namespace search { namespace @@ -53,17 +57,58 @@ void CoverRect(m2::RectD const & rect, int scale, covering::IntervalsT & result) result.insert(result.end(), intervals.begin(), intervals.end()); } +bool MatchFeatureByName(FeatureType const & ft, SearchQueryParams const & params) +{ + bool matched = false; + auto const matcher = [&](int8_t /*lang*/, string const & utf8Name) -> bool + { + auto const name = search::NormalizeAndSimplifyString(utf8Name); + for (auto const & prefix : params.m_prefixTokens) + { + if (strings::StartsWith(name, prefix)) + { + matched = true; + return false; + } + } + for (auto const & synonyms : params.m_tokens) + { + for (auto const & token : synonyms) + { + if (token == name) + { + matched = true; + return false; + } + } + } + return true; // To iterate all names. + }; + ft.ForEachName(matcher); + return matched; +} + // Retrieves from the search index corresponding to |value| all // features matching to |params|. template unique_ptr RetrieveAddressFeaturesImpl( - MwmValue & value, my::Cancellable const & cancellable, SearchQueryParams const & params) + MwmSet::MwmId const & id, MwmValue & value, my::Cancellable const & cancellable, + SearchQueryParams const & params) { serial::CodingParams codingParams(trie::GetCodingParams(value.GetHeader().GetDefCodingParams())); ModelReaderPtr searchReader = value.m_cont.GetReader(SEARCH_INDEX_FILE_TAG); - auto emptyFilter = [](uint32_t /* featureId */) + // Exclude from search all deleted/modified features and match all edited/created features separately. + Editor & editor = Editor::Instance(); + auto const deleted = editor.GetFeaturesByStatus(id, Editor::FeatureStatus::Deleted); + // Modified features should be re-matched again. + auto const modified = editor.GetFeaturesByStatus(id, Editor::FeatureStatus::Modified); + auto const filter = [&](uint32_t featureIndex) -> bool { + if (binary_search(deleted.begin(), deleted.end(), featureIndex)) + return false; + if (binary_search(modified.begin(), modified.end(), featureIndex)) + return false; return true; }; @@ -74,29 +119,47 @@ unique_ptr RetrieveAddressFeaturesImpl( // bit vectors are sorted in the search index. vector features; uint32_t counter = 0; - auto collector = [&](TValue const & value) + auto const collector = [&](TValue const & value) { if ((++counter & 0xFF) == 0) BailIfCancelled(cancellable); features.push_back(value.m_featureId); }; - MatchFeaturesInTrie(params, *trieRoot, emptyFilter, collector); + MatchFeaturesInTrie(params, *trieRoot, filter, collector); + + // Match all edited/created features separately. + auto const matcher = [&](uint32_t featureIndex) + { + FeatureType ft; + VERIFY(editor.GetEditedFeature(id, featureIndex, ft), ()); + // TODO(AlexZ): Should we match by some feature's metafields too? + if (MatchFeatureByName(ft, params)) + features.push_back(featureIndex); + }; + for_each(modified.begin(), modified.end(), matcher); + auto const created = editor.GetFeaturesByStatus(id, Editor::FeatureStatus::Created); + for_each(created.begin(), created.end(), matcher); + return SortFeaturesAndBuildCBV(move(features)); } // Retrieves from the geometry index corresponding to handle all // features from |coverage|. unique_ptr RetrieveGeometryFeaturesImpl( - MwmValue & value, my::Cancellable const & cancellable, covering::IntervalsT const & coverage, - int scale) + MwmSet::MwmId const & id, MwmValue & value, my::Cancellable const & cancellable, + covering::IntervalsT const & coverage, int scale) { + // TODO(AlexZ): Also add created features. + auto const deleted = Editor::Instance().GetFeaturesByStatus(id, Editor::FeatureStatus::Deleted); // TODO (@y, @m): remove this code as soon as geometry index will // have native support for bit vectors. vector features; uint32_t counter = 0; - auto collector = [&](uint64_t featureId) + auto const collector = [&](uint64_t featureId) { + if (binary_search(deleted.begin(), deleted.end(), static_cast(featureId))) + return; if ((++counter & 0xFF) == 0) BailIfCancelled(cancellable); features.push_back(featureId); @@ -233,8 +296,9 @@ public: { covering::IntervalsT coverage; CoverRect(currViewport, m_coverageScale, coverage); - geometryFeatures = RetrieveGeometryFeaturesImpl(*m_handle.GetValue(), cancellable, - coverage, m_coverageScale); + geometryFeatures = + RetrieveGeometryFeaturesImpl(m_handle.GetId(), *m_handle.GetValue(), + cancellable, coverage, m_coverageScale); for (auto const & interval : coverage) m_visited.Add(interval); } @@ -267,8 +331,9 @@ public: for (auto const & interval : coverage) m_visited.SubtractFrom(interval, reducedCoverage); - geometryFeatures = RetrieveGeometryFeaturesImpl(*m_handle.GetValue(), cancellable, - reducedCoverage, m_coverageScale); + geometryFeatures = + RetrieveGeometryFeaturesImpl(m_handle.GetId(), *m_handle.GetValue(), + cancellable, reducedCoverage, m_coverageScale); for (auto const & interval : reducedCoverage) m_visited.Add(interval); @@ -367,7 +432,8 @@ Retrieval::Retrieval() : m_index(nullptr), m_featuresReported(0) {} // static unique_ptr Retrieval::RetrieveAddressFeatures( - MwmValue & value, my::Cancellable const & cancellable, SearchQueryParams const & params) + MwmSet::MwmId const & id, MwmValue & value, my::Cancellable const & cancellable, + SearchQueryParams const & params) { MwmTraits mwmTraits(value.GetMwmVersion().format); @@ -375,24 +441,25 @@ unique_ptr Retrieval::RetrieveAddressFeatures( MwmTraits::SearchIndexFormat::FeaturesWithRankAndCenter) { using TValue = FeatureWithRankAndCenter; - return RetrieveAddressFeaturesImpl(value, cancellable, params); + return RetrieveAddressFeaturesImpl(id, value, cancellable, params); } else if (mwmTraits.GetSearchIndexFormat() == MwmTraits::SearchIndexFormat::CompressedBitVector) { using TValue = FeatureIndexValue; - return RetrieveAddressFeaturesImpl(value, cancellable, params); + return RetrieveAddressFeaturesImpl(id, value, cancellable, params); } return unique_ptr(); } // static unique_ptr Retrieval::RetrieveGeometryFeatures( - MwmValue & value, my::Cancellable const & cancellable, m2::RectD const & rect, int scale) + MwmSet::MwmId const & id, MwmValue & value, my::Cancellable const & cancellable, + m2::RectD const & rect, int scale) { covering::IntervalsT coverage; CoverRect(rect, scale, coverage); - return RetrieveGeometryFeaturesImpl(value, cancellable, coverage, scale); + return RetrieveGeometryFeaturesImpl(id, value, cancellable, coverage, scale); } void Retrieval::Init(Index & index, vector> const & infos, @@ -526,8 +593,8 @@ bool Retrieval::InitBucketStrategy(Bucket & bucket, double scale) try { addressFeatures = - RetrieveAddressFeatures(*bucket.m_handle.GetValue(), *this /* cancellable */, - m_params); + RetrieveAddressFeatures(bucket.m_handle.GetId(), *bucket.m_handle.GetValue(), + *this /* cancellable */, m_params); } catch (CancelException &) { diff --git a/search/retrieval.hpp b/search/retrieval.hpp index f837f38f72..6b363ab70d 100644 --- a/search/retrieval.hpp +++ b/search/retrieval.hpp @@ -107,11 +107,13 @@ public: // Retrieves from the search index corresponding to |value| all // features matching to |params|. WARN_UNUSED_RESULT static unique_ptr RetrieveAddressFeatures( - MwmValue & value, my::Cancellable const & cancellable, SearchQueryParams const & params); + MwmSet::MwmId const & id, MwmValue & value, my::Cancellable const & cancellable, + SearchQueryParams const & params); // Retrieves from the geometry index corresponding to |value| all features belonging to |rect|. WARN_UNUSED_RESULT static unique_ptr RetrieveGeometryFeatures( - MwmValue & value, my::Cancellable const & cancellable, m2::RectD const & rect, int scale); + MwmSet::MwmId const & id, MwmValue & value, my::Cancellable const & cancellable, + m2::RectD const & rect, int scale); // Initializes retrieval process, sets up internal state, takes all // necessary system resources. diff --git a/search/v2/geocoder.cpp b/search/v2/geocoder.cpp index d935fe8de2..9753e8aa28 100644 --- a/search/v2/geocoder.cpp +++ b/search/v2/geocoder.cpp @@ -460,9 +460,9 @@ void Geocoder::GoImpl(vector> & infos, bool inViewport) unique_ptr viewportCBV; if (inViewport) { - viewportCBV = Retrieval::RetrieveGeometryFeatures( - m_context->m_value, cancellable, - m_params.m_viewport, m_params.m_scale); + viewportCBV = + Retrieval::RetrieveGeometryFeatures(m_context->m_id, m_context->m_value, cancellable, + m_params.m_viewport, m_params.m_scale); } // Creates a cache of posting lists for each token. @@ -472,7 +472,7 @@ void Geocoder::GoImpl(vector> & infos, bool inViewport) PrepareRetrievalParams(i, i + 1); m_addressFeatures[i] = Retrieval::RetrieveAddressFeatures( - m_context->m_value, cancellable, m_retrievalParams); + m_context->m_id, m_context->m_value, cancellable, m_retrievalParams); ASSERT(m_addressFeatures[i], ()); if (viewportCBV) @@ -535,7 +535,8 @@ void Geocoder::FillLocalitiesTable(MwmContext const & context) { PrepareRetrievalParams(i, i + 1); tokensCBV.push_back(Retrieval::RetrieveAddressFeatures( - context.m_value, static_cast(*this), m_retrievalParams)); + context.m_id, context.m_value, static_cast(*this), + m_retrievalParams)); } // 2. Get all locality candidates for the continuous token ranges. @@ -1119,7 +1120,7 @@ coding::CompressedBitVector const * Geocoder::LoadStreets(MwmContext & context) { m_retrievalParams.m_tokens[0][0] = category; auto streets = Retrieval::RetrieveAddressFeatures( - context.m_value, *this /* cancellable */, + context.m_id, context.m_value, *this /* cancellable */, m_retrievalParams); if (!coding::CompressedBitVector::IsEmpty(streets)) streetsList.push_back(move(streets)); @@ -1160,8 +1161,9 @@ coding::CompressedBitVector const * Geocoder::RetrieveGeometryFeatures(MwmContex return v.m_cbv.get(); } - auto cbv = Retrieval::RetrieveGeometryFeatures( - context.m_value, static_cast(*this), rect, m_params.m_scale); + auto cbv = Retrieval::RetrieveGeometryFeatures(context.m_id, context.m_value, + static_cast(*this), rect, + m_params.m_scale); auto const * result = cbv.get(); features.push_back({m2::Inflate(rect, kComparePoints, kComparePoints), move(cbv), id});