Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuri Gorshenin <y@maps.me>2015-09-14 14:49:44 +0300
committerSergey Yershov <yershov@corp.mail.ru>2016-03-23 16:02:15 +0300
commit04d391103221d2f449212ef20b72b219094bead1 (patch)
tree103d33eb282a4dc8296f03f36606028b76a14dfb /search/retrieval.cpp
parent044d4a2dd071ca0c29aae84a7ae20104cbcd0d8c (diff)
[search] Added more cancellable checks to retrieval.
Diffstat (limited to 'search/retrieval.cpp')
-rw-r--r--search/retrieval.cpp143
1 files changed, 84 insertions, 59 deletions
diff --git a/search/retrieval.cpp b/search/retrieval.cpp
index bffed86a9d..270aed32d8 100644
--- a/search/retrieval.cpp
+++ b/search/retrieval.cpp
@@ -20,6 +20,12 @@ namespace search
{
namespace
{
+// This exception can be thrown by callbacks from deeps of search and
+// geometry retrieval for fast cancellation of time-consuming tasks.
+struct CancelException
+{
+};
+
// Upper bound on a number of features when fast path is used.
// Otherwise, slow path is used.
uint64_t constexpr kFastPathThreshold = 100;
@@ -31,8 +37,9 @@ struct EmptyFilter
// Retrieves from the search index corresponding to |handle| all
// features matching to |params|.
+template <typename ToDo>
void RetrieveAddressFeatures(MwmSet::MwmHandle const & handle, SearchQueryParams const & params,
- vector<uint32_t> & featureIds)
+ ToDo && toDo)
{
auto * value = handle.GetValue<MwmValue>();
ASSERT(value, ());
@@ -42,11 +49,7 @@ void RetrieveAddressFeatures(MwmSet::MwmHandle const & handle, SearchQueryParams
trie::ReadTrie(SubReaderWrapper<Reader>(searchReader.GetPtr()),
trie::ValueReader(codingParams), trie::TEdgeValueReader()));
- auto collector = [&](trie::ValueReader::ValueType const & value)
- {
- featureIds.push_back(value.m_featureId);
- };
- MatchFeaturesInTrie(params, *trieRoot, EmptyFilter(), collector);
+ MatchFeaturesInTrie(params, *trieRoot, EmptyFilter(), forward<ToDo>(toDo));
}
// Retrieves from the geomery index corresponding to handle all
@@ -151,48 +154,51 @@ public:
bool RetrieveImpl(double scale, my::Cancellable const & cancellable,
TCallback const & callback) override
{
-#define LONG_OP(op) \
- { \
- if (cancellable.IsCancelled()) \
- return false; \
- op; \
- }
-
m2::RectD currViewport = m_viewport;
currViewport.Scale(scale);
vector<uint32_t> geometryFeatures;
- auto collector = [&](uint32_t feature)
+
+ try
{
- if (feature < m_nonReported.size() && m_nonReported[feature])
+ auto collector = [&](uint32_t feature)
{
- geometryFeatures.push_back(feature);
- m_nonReported[feature] = false;
- }
- };
+ if (cancellable.IsCancelled())
+ throw CancelException();
- if (m_prevScale < 0)
- {
- LONG_OP(RetrieveGeometryFeatures(m_handle, currViewport, m_params, collector));
+ if (feature < m_nonReported.size() && m_nonReported[feature])
+ {
+ geometryFeatures.push_back(feature);
+ m_nonReported[feature] = false;
+ }
+ };
+
+ if (m_prevScale < 0)
+ {
+ RetrieveGeometryFeatures(m_handle, currViewport, m_params, collector);
+ }
+ else
+ {
+ m2::RectD prevViewport = m_viewport;
+ prevViewport.Scale(m_prevScale);
+
+ m2::RectD a(currViewport.LeftTop(), prevViewport.RightTop());
+ m2::RectD c(currViewport.RightBottom(), prevViewport.LeftBottom());
+ m2::RectD b(a.RightTop(), c.RightTop());
+ m2::RectD d(a.LeftBottom(), c.LeftBottom());
+
+ RetrieveGeometryFeatures(m_handle, a, m_params, collector);
+ RetrieveGeometryFeatures(m_handle, b, m_params, collector);
+ RetrieveGeometryFeatures(m_handle, c, m_params, collector);
+ RetrieveGeometryFeatures(m_handle, d, m_params, collector);
+ }
}
- else
+ catch (CancelException &)
{
- m2::RectD prevViewport = m_viewport;
- prevViewport.Scale(m_prevScale);
-
- m2::RectD a(currViewport.LeftTop(), prevViewport.RightTop());
- m2::RectD c(currViewport.RightBottom(), prevViewport.LeftBottom());
- m2::RectD b(a.RightTop(), c.RightTop());
- m2::RectD d(a.LeftBottom(), c.LeftBottom());
-
- LONG_OP(RetrieveGeometryFeatures(m_handle, a, m_params, collector));
- LONG_OP(RetrieveGeometryFeatures(m_handle, b, m_params, collector));
- LONG_OP(RetrieveGeometryFeatures(m_handle, c, m_params, collector));
- LONG_OP(RetrieveGeometryFeatures(m_handle, d, m_params, collector));
+ return false;
}
callback(geometryFeatures);
-#undef LONG_OP
return true;
}
@@ -340,50 +346,35 @@ bool Retrieval::RetrieveForScale(double scale, Callback & callback)
if (!bucket.m_intersectsWithViewport)
{
- // This is the first time viewport intersects with mwm. Retrieve
- // all matching features from the search index.
- ASSERT(!bucket.m_strategy, ());
- RetrieveAddressFeatures(bucket.m_handle, m_params, bucket.m_addressFeatures);
- if (IsCancelled())
+ // This is the first time viewport intersects with
+ // mwm. Initialize bucket's retrieval strategy.
+ if (!InitBucketStrategy(bucket))
return false;
- if (bucket.m_addressFeatures.size() < kFastPathThreshold)
- {
- bucket.m_strategy.reset(
- new FastPathStrategy(*m_index, bucket.m_handle, m_viewport, bucket.m_addressFeatures));
- }
- else
- {
- bucket.m_strategy.reset(
- new SlowPathStrategy(bucket.m_handle, m_viewport, m_params, bucket.m_addressFeatures));
- }
-
bucket.m_intersectsWithViewport = true;
- if (bucket.m_addressFeatures.empty())
- FinishBucket(bucket, callback);
}
+ ASSERT(bucket.m_intersectsWithViewport, ());
ASSERT_LESS_OR_EQUAL(bucket.m_featuresReported, bucket.m_addressFeatures.size(), ());
if (bucket.m_featuresReported == bucket.m_addressFeatures.size())
{
// All features were reported for the bucket, mark it as
// finished and move to the next bucket.
- ASSERT(bucket.m_intersectsWithViewport, ());
FinishBucket(bucket, callback);
continue;
}
- Strategy::TCallback wrapper = [&](vector<uint32_t> & features)
+ auto wrapper = [&](vector<uint32_t> & features)
{
ReportFeatures(bucket, features, scale, callback);
};
+
if (!bucket.m_strategy->Retrieve(scale, *this /* cancellable */, wrapper))
return false;
if (viewport.IsRectInside(bucket.m_bounds))
{
- ASSERT(bucket.m_intersectsWithViewport, ());
- // Viewport completely covers the bucket, mark it as finished
- // and move to the next bucket. Note that "viewport covers the
+ // Viewport completely covers the bucket, so mark it as finished
+ // and switch to the next bucket. Note that "viewport covers the
// bucket" is not the same as "all features from the bucket were
// reported", because of scale parameter. Search index reports
// all matching features, but geometry index can skip features
@@ -396,6 +387,40 @@ bool Retrieval::RetrieveForScale(double scale, Callback & callback)
return true;
}
+bool Retrieval::InitBucketStrategy(Bucket & bucket)
+{
+ ASSERT(!bucket.m_strategy, ());
+ ASSERT(bucket.m_addressFeatures.empty(), ());
+
+ try
+ {
+ auto collector = [&](trie::ValueReader::ValueType const & value)
+ {
+ if (IsCancelled())
+ throw CancelException();
+ bucket.m_addressFeatures.push_back(value.m_featureId);
+ };
+ RetrieveAddressFeatures(bucket.m_handle, m_params, collector);
+ }
+ catch (CancelException &)
+ {
+ return false;
+ }
+
+ if (bucket.m_addressFeatures.size() < kFastPathThreshold)
+ {
+ bucket.m_strategy.reset(
+ new FastPathStrategy(*m_index, bucket.m_handle, m_viewport, bucket.m_addressFeatures));
+ }
+ else
+ {
+ bucket.m_strategy.reset(
+ new SlowPathStrategy(bucket.m_handle, m_viewport, m_params, bucket.m_addressFeatures));
+ }
+
+ return true;
+}
+
void Retrieval::FinishBucket(Bucket & bucket, Callback & callback)
{
if (bucket.m_finished)