diff --git a/search/features_layer_path_finder.cpp b/search/features_layer_path_finder.cpp index 711c12251f..f19af9058d 100644 --- a/search/features_layer_path_finder.cpp +++ b/search/features_layer_path_finder.cpp @@ -9,6 +9,12 @@ #include "base/cancellable.hpp" #include "base/stl_helpers.hpp" +#include +#include +#include + +using namespace std; + namespace search { // static @@ -16,7 +22,7 @@ FeaturesLayerPathFinder::Mode FeaturesLayerPathFinder::m_mode = MODE_AUTO; namespace { -using TParentGraph = unordered_map; +using ParentGraph = deque>; // This function tries to estimate amount of work needed to perform an // intersection pass on a sequence of layers. @@ -48,22 +54,25 @@ uint64_t CalcBottomUpPassCost(vector const & layers) return CalcPassCost(layers.begin(), layers.end()); } -bool GetPath(uint32_t id, vector const & layers, TParentGraph const & parent, +bool GetPath(uint32_t id, vector const & layers, ParentGraph const & parent, IntersectionResult & result) { result.Clear(); + if (layers.size() != parent.size() + 1) + return false; size_t level = 0; - TParentGraph::const_iterator it; - do + for (auto parentGraphLayer = parent.crbegin(); parentGraphLayer != parent.crend(); + ++parentGraphLayer, ++level) { result.Set(layers[level]->m_type, id); - ++level; - it = parent.find(id); - if (it != parent.cend()) - id = it->second; - } while (level < layers.size() && it != parent.cend()); - return level == layers.size(); + auto const it = parentGraphLayer->find(id); + if (it == parentGraphLayer->cend()) + return false; + id = it->second; + } + result.Set(layers[level]->m_type, id); + return true; } bool MayHaveDelayedFeatures(FeaturesLayer const & layer) @@ -112,9 +121,10 @@ void FeaturesLayerPathFinder::FindReachableVerticesTopDown( vector reachable = *(layers.back()->m_sortedFeatures); vector buffer; - TParentGraph parent; + ParentGraph parentGraph; auto addEdge = [&](uint32_t childFeature, uint32_t parentFeature) { + auto & parent = parentGraph.back(); if (parent.find(childFeature) != parent.end()) return; parent[childFeature] = parentFeature; @@ -125,6 +135,7 @@ void FeaturesLayerPathFinder::FindReachableVerticesTopDown( { BailIfCancelled(m_cancellable); + parentGraph.emplace_back(); FeaturesLayer parent(*layers[i]); if (i != layers.size() - 1) my::SortUnique(reachable); @@ -147,7 +158,7 @@ void FeaturesLayerPathFinder::FindReachableVerticesTopDown( IntersectionResult result; for (auto const & id : lowestLevel) { - if (GetPath(id, layers, parent, result)) + if (GetPath(id, layers, parentGraph, result)) results.push_back(result); } } @@ -161,7 +172,7 @@ void FeaturesLayerPathFinder::FindReachableVerticesBottomUp( vector reachable = *(layers.front()->m_sortedFeatures); vector buffer; - TParentGraph parent; + ParentGraph parentGraph; // It is possible that there are delayed features on the lowest level. // We do not know about them until the matcher has been called, so @@ -174,6 +185,7 @@ void FeaturesLayerPathFinder::FindReachableVerticesBottomUp( bool first = true; auto addEdge = [&](uint32_t childFeature, uint32_t parentFeature) { + auto & parent = parentGraph.front(); if (parent.find(childFeature) != parent.end()) return; parent[childFeature] = parentFeature; @@ -187,6 +199,7 @@ void FeaturesLayerPathFinder::FindReachableVerticesBottomUp( { BailIfCancelled(m_cancellable); + parentGraph.emplace_front(); FeaturesLayer child(*layers[i]); if (i != 0) my::SortUnique(reachable); @@ -208,7 +221,7 @@ void FeaturesLayerPathFinder::FindReachableVerticesBottomUp( IntersectionResult result; for (auto const & id : lowestLevel) { - if (GetPath(id, layers, parent, result)) + if (GetPath(id, layers, parentGraph, result)) results.push_back(result); } } diff --git a/search/features_layer_path_finder.hpp b/search/features_layer_path_finder.hpp index 0af748a4a8..982b06b28d 100644 --- a/search/features_layer_path_finder.hpp +++ b/search/features_layer_path_finder.hpp @@ -3,7 +3,7 @@ #include "search/features_layer.hpp" #include "search/intersection_result.hpp" -#include "std/vector.hpp" +#include #if defined(DEBUG) #include "base/logging.hpp" @@ -49,7 +49,7 @@ public: template void ForEachReachableVertex(FeaturesLayerMatcher & matcher, - vector const & layers, TFn && fn) + std::vector const & layers, TFn && fn) { if (layers.empty()) return; @@ -63,7 +63,7 @@ public: my::Timer timer; #endif // defined(DEBUG) - vector results; + std::vector results; FindReachableVertices(matcher, layers, results); #if defined(DEBUG) @@ -77,20 +77,20 @@ public: private: void FindReachableVertices(FeaturesLayerMatcher & matcher, - vector const & layers, - vector & results); + std::vector const & layers, + std::vector & results); // Tries to find all |reachable| features from the lowest layer in a // high level -> low level pass. void FindReachableVerticesTopDown(FeaturesLayerMatcher & matcher, - vector const & layers, - vector & results); + std::vector const & layers, + std::vector & results); // Tries to find all |reachable| features from the lowest layer in a // low level -> high level pass. void FindReachableVerticesBottomUp(FeaturesLayerMatcher & matcher, - vector const & layers, - vector & results); + std::vector const & layers, + std::vector & results); ::base::Cancellable const & m_cancellable;