From b58d76045d7f1ee85b73f6f5cf79c56876bf412a Mon Sep 17 00:00:00 2001 From: Yuri Gorshenin Date: Mon, 14 Dec 2015 18:27:16 +0300 Subject: [PATCH] [search] my::Cancellable is exposed to Geocoder's helper classes. --- search/cancel_exception.hpp | 17 +++++++++++++++++ search/retrieval.cpp | 1 + search/retrieval.hpp | 8 -------- search/search.pro | 1 + search/v2/features_layer_matcher.cpp | 4 +++- search/v2/features_layer_matcher.hpp | 20 +++++++++++++++++++- search/v2/features_layer_path_finder.cpp | 10 ++++++++++ search/v2/features_layer_path_finder.hpp | 9 +++++++++ search/v2/geocoder.cpp | 13 ++++++++----- 9 files changed, 68 insertions(+), 15 deletions(-) create mode 100644 search/cancel_exception.hpp diff --git a/search/cancel_exception.hpp b/search/cancel_exception.hpp new file mode 100644 index 0000000000..c4c1950083 --- /dev/null +++ b/search/cancel_exception.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include "base/cancellable.hpp" +#include "base/exception.hpp" + +namespace search +{ +// This exception can be thrown from the deep darkness of search and +// geometry retrieval for fast cancellation of time-consuming tasks. +DECLARE_EXCEPTION(CancelException, RootException); + +inline void BailIfCancelled(my::Cancellable const & cancellable) +{ + if (cancellable.IsCancelled()) + MYTHROW(CancelException, ("Cancelled")); +} +} // namespace search diff --git a/search/retrieval.cpp b/search/retrieval.cpp index ec5924206b..ad94837e8a 100644 --- a/search/retrieval.cpp +++ b/search/retrieval.cpp @@ -1,5 +1,6 @@ #include "retrieval.hpp" +#include "cancel_exception.hpp" #include "feature_offset_match.hpp" #include "interval_set.hpp" #include "mwm_traits.hpp" diff --git a/search/retrieval.hpp b/search/retrieval.hpp index 36ea1810ee..fea915d8fd 100644 --- a/search/retrieval.hpp +++ b/search/retrieval.hpp @@ -7,7 +7,6 @@ #include "geometry/rect2d.hpp" #include "base/cancellable.hpp" -#include "base/exception.hpp" #include "base/macros.hpp" #include "std/function.hpp" @@ -24,13 +23,6 @@ class CompressedBitVector; namespace search { -// This exception can be thrown by callbacks from deeps of search and -// geometry retrieval for fast cancellation of time-consuming tasks. -// -// TODO (@gorshenin): after merge to master, move this class to -// base/cancellable.hpp. -DECLARE_EXCEPTION(CancelException, RootException); - class Retrieval : public my::Cancellable { public: diff --git a/search/search.pro b/search/search.pro index ca965ad112..179229d3f3 100644 --- a/search/search.pro +++ b/search/search.pro @@ -11,6 +11,7 @@ include($$ROOT_DIR/common.pri) HEADERS += \ algos.hpp \ approximate_string_match.hpp \ + cancel_exception.hpp \ categories_holder.hpp \ dummy_rank_table.hpp \ feature_offset_match.hpp \ diff --git a/search/v2/features_layer_matcher.cpp b/search/v2/features_layer_matcher.cpp index 9ccf17baf6..20d80e408c 100644 --- a/search/v2/features_layer_matcher.cpp +++ b/search/v2/features_layer_matcher.cpp @@ -11,12 +11,14 @@ namespace search namespace v2 { FeaturesLayerMatcher::FeaturesLayerMatcher(Index & index, MwmSet::MwmId const & mwmId, - MwmValue & value, FeaturesVector const & featuresVector) + MwmValue & value, FeaturesVector const & featuresVector, + my::Cancellable const & cancellable) : m_mwmId(mwmId) , m_reverseGeocoder(index) , m_houseToStreetTable(HouseToStreetTable::Load(value)) , m_featuresVector(featuresVector) , m_loader(value, featuresVector, scales::GetUpperScale(), ReverseGeocoder::kLookupRadiusM) + , m_cancellable(cancellable) { ASSERT(m_houseToStreetTable.get(), ("Can't load HouseToStreetTable")); } diff --git a/search/v2/features_layer_matcher.hpp b/search/v2/features_layer_matcher.hpp index 30a2283df7..2b625b0508 100644 --- a/search/v2/features_layer_matcher.hpp +++ b/search/v2/features_layer_matcher.hpp @@ -1,5 +1,6 @@ #pragma once +#include "search/cancel_exception.hpp" #include "search/reverse_geocoder.hpp" #include "search/v2/features_layer.hpp" #include "search/v2/house_numbers_matcher.hpp" @@ -17,6 +18,7 @@ #include "geometry/point2d.hpp" #include "geometry/rect2d.hpp" +#include "base/cancellable.hpp" #include "base/macros.hpp" #include "base/stl_helpers.hpp" @@ -50,7 +52,7 @@ class FeaturesLayerMatcher { public: FeaturesLayerMatcher(Index & index, MwmSet::MwmId const & mwmId, MwmValue & value, - FeaturesVector const & featuresVector); + FeaturesVector const & featuresVector, my::Cancellable const & cancellable); template void Match(FeaturesLayer const & child, vector const & sortedParentFeatures, @@ -75,6 +77,8 @@ public: childCenters.push_back(feature::GetCenter(ft, FeatureType::WORST_GEOMETRY)); } + BailIfCancelled(m_cancellable); + vector parentRects; for (uint32_t featureId : sortedParentFeatures) { @@ -87,6 +91,8 @@ public: for (size_t j = 0; j < sortedParentFeatures.size(); ++j) { + BailIfCancelled(m_cancellable); + for (size_t i = 0; i < child.m_sortedFeatures.size(); ++i) { if (parentRects[j].IsPointInside(childCenters[i])) @@ -105,7 +111,10 @@ private: ASSERT_EQUAL(parentType, SearchModel::SEARCH_TYPE_STREET, ()); for (uint32_t streetId : sortedParentFeatures) + { + BailIfCancelled(m_cancellable); m_loader.ForEachInVicinity(streetId, child.m_sortedFeatures, bind(fn, _1, streetId)); + } } template @@ -126,8 +135,13 @@ private: vector queryTokens; NormalizeHouseNumber(child.m_subQuery, queryTokens); + uint32_t numFilterInvocations = 0; auto filter = [&](uint32_t id, FeatureType & feature) -> bool { + ++numFilterInvocations; + if ((numFilterInvocations & 0xFF) == 0) + BailIfCancelled(m_cancellable); + if (!checker(feature)) return false; if (binary_search(child.m_sortedFeatures.begin(), child.m_sortedFeatures.end(), id)) @@ -149,7 +163,10 @@ private: }; for (uint32_t streetId : sortedParentFeatures) + { + BailIfCancelled(m_cancellable); m_loader.FilterFeaturesInVicinity(streetId, filter, bind(addEdge, _1, _2, streetId)); + } } MwmSet::MwmId m_mwmId; @@ -157,6 +174,7 @@ private: unique_ptr m_houseToStreetTable; FeaturesVector const & m_featuresVector; StreetVicinityLoader m_loader; + my::Cancellable const & m_cancellable; }; } // namespace v2 } // namespace search diff --git a/search/v2/features_layer_path_finder.cpp b/search/v2/features_layer_path_finder.cpp index 6a0ba2e332..9bdf26cddd 100644 --- a/search/v2/features_layer_path_finder.cpp +++ b/search/v2/features_layer_path_finder.cpp @@ -1,13 +1,21 @@ #include "search/v2/features_layer_path_finder.hpp" +#include "search/cancel_exception.hpp" #include "search/v2/features_layer_matcher.hpp" #include "indexer/features_vector.hpp" +#include "base/cancellable.hpp" + namespace search { namespace v2 { +FeaturesLayerPathFinder::FeaturesLayerPathFinder(my::Cancellable const & cancellable) + : m_cancellable(cancellable) +{ +} + void FeaturesLayerPathFinder::BuildGraph(FeaturesLayerMatcher & matcher, vector const & layers, vector & reachable) @@ -25,6 +33,8 @@ void FeaturesLayerPathFinder::BuildGraph(FeaturesLayerMatcher & matcher, // STREETs first, and then POIs with BUILDINGs. for (size_t i = layers.size() - 1; i != 0; --i) { + BailIfCancelled(m_cancellable); + tmpBuffer.clear(); auto addEdge = [&](uint32_t childFeature, uint32_t /* parentFeature */) { diff --git a/search/v2/features_layer_path_finder.hpp b/search/v2/features_layer_path_finder.hpp index 416ad60c91..719025e3f7 100644 --- a/search/v2/features_layer_path_finder.hpp +++ b/search/v2/features_layer_path_finder.hpp @@ -7,6 +7,11 @@ class FeaturesVector; class MwmValue; +namespace my +{ +class Cancellable; +} + namespace search { namespace v2 @@ -25,6 +30,8 @@ class FeaturesLayerMatcher; class FeaturesLayerPathFinder { public: + FeaturesLayerPathFinder(my::Cancellable const & cancellable); + template void ForEachReachableVertex(FeaturesLayerMatcher & matcher, vector const & layers, TFn && fn) @@ -42,6 +49,8 @@ public: private: void BuildGraph(FeaturesLayerMatcher & matcher, vector const & layers, vector & reachable); + + my::Cancellable const & m_cancellable; }; } // namespace v2 } // namespace search diff --git a/search/v2/geocoder.cpp b/search/v2/geocoder.cpp index fe2ba80b91..6d0aea951f 100644 --- a/search/v2/geocoder.cpp +++ b/search/v2/geocoder.cpp @@ -1,9 +1,10 @@ #include "search/v2/geocoder.hpp" +#include "search/cancel_exception.hpp" #include "search/retrieval.hpp" -#include "search/v2/features_layer_matcher.hpp" #include "search/search_delimiters.hpp" #include "search/search_string_utils.hpp" +#include "search/v2/features_layer_matcher.hpp" #include "indexer/feature_decl.hpp" #include "indexer/feature_impl.hpp" @@ -55,6 +56,7 @@ Geocoder::Geocoder(Index & index) , m_numTokens(0) , m_model(SearchModel::Instance()) , m_value(nullptr) + , m_finder(static_cast(*this)) , m_results(nullptr) { } @@ -105,8 +107,8 @@ void Geocoder::Go(vector & results) m_cache.clear(); m_loader.reset(new Index::FeaturesLoaderGuard(m_index, m_mwmId)); - m_matcher.reset( - new FeaturesLayerMatcher(m_index, m_mwmId, *m_value, m_loader->GetFeaturesVector())); + m_matcher.reset(new FeaturesLayerMatcher( + m_index, m_mwmId, *m_value, m_loader->GetFeaturesVector(), *this /* cancellable */)); DoGeocoding(0 /* curToken */); } @@ -138,8 +140,7 @@ void Geocoder::PrepareParams(size_t curToken, size_t endToken) void Geocoder::DoGeocoding(size_t curToken) { - if (IsCancelled()) - MYTHROW(CancelException, ("Cancelled.")); + BailIfCancelled(static_cast(*this)); if (curToken == m_numTokens) { @@ -155,6 +156,8 @@ void Geocoder::DoGeocoding(size_t curToken) // Try to consume first n tokens starting at |curToken|. for (size_t n = 1; curToken + n <= m_numTokens; ++n) { + BailIfCancelled(static_cast(*this)); + PrepareParams(curToken, curToken + n); { auto & layer = m_layers.back();