From 63754df4d4980c7bab38efa77bd3439762e76cd2 Mon Sep 17 00:00:00 2001 From: Patrick Niklaus Date: Sat, 30 Apr 2016 04:19:03 +0200 Subject: [PATCH] Add cache for CandidateSegments to reduce heap worke even more --- include/util/static_rtree.hpp | 39 ++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/include/util/static_rtree.hpp b/include/util/static_rtree.hpp index c9c031a4c..acdeeebd9 100644 --- a/include/util/static_rtree.hpp +++ b/include/util/static_rtree.hpp @@ -43,7 +43,8 @@ template , bool UseSharedMemory = false, std::uint32_t BRANCHING_FACTOR = 64, - std::uint32_t LEAF_NODE_SIZE = 256> + std::uint32_t LEAF_NODE_SIZE = 256, + std::uint32_t MAX_NUM_CANDIDATES = LEAF_NODE_SIZE * 10> class StaticRTree { public: @@ -93,7 +94,9 @@ class StaticRTree } }; - using QueryNodeType = mapbox::util::variant; + struct TreeIndex { std::uint32_t index; }; + struct SegmentIndex { std::uint32_t index; }; + using QueryNodeType = mapbox::util::variant; struct QueryCandidate { inline bool operator<(const QueryCandidate &other) const @@ -415,21 +418,26 @@ class StaticRTree // initialize queue with root element std::priority_queue traversal_queue; - traversal_queue.push(QueryCandidate{0, 0}); + traversal_queue.push(QueryCandidate{0, TreeIndex{0}}); + + // we need to limit the size of this vector to MAX_NUM_CANDIDATES + // otherwise this could fill up + std::vector candidate_cache; + candidate_cache.reserve(LEAF_NODE_SIZE); while (!traversal_queue.empty()) { QueryCandidate current_query_node = traversal_queue.top(); traversal_queue.pop(); - if (current_query_node.node.template is()) + if (current_query_node.node.template is()) { // current object is a tree node const TreeNode ¤t_tree_node = - m_search_tree[current_query_node.node.template get()]; + m_search_tree[current_query_node.node.template get().index]; if (current_tree_node.child_is_on_disk) { ExploreLeafNode(current_tree_node.children[0], fixed_projected_coordinate, - projected_coordinate, traversal_queue); + projected_coordinate, traversal_queue, candidate_cache); } else { @@ -439,7 +447,7 @@ class StaticRTree else { // inspecting an actual road segment - auto ¤t_candidate = current_query_node.node.template get(); + auto ¤t_candidate = candidate_cache[current_query_node.node.template get().index]; // to allow returns of no-results if too restrictive filtering, this needs to be done here // even though performance would indicate that we want to stop after adding the first candidate @@ -470,8 +478,16 @@ class StaticRTree void ExploreLeafNode(const std::uint32_t leaf_id, const Coordinate projected_input_coordinate_fixed, const FloatCoordinate &projected_input_coordinate, - QueueT &traversal_queue) + QueueT &traversal_queue, + std::vector &candidate_cache) { + // we are not going to load any more elements, because the cache would + // fill up + if (candidate_cache.size() > MAX_NUM_CANDIDATES) + { + return; + } + LeafNode current_leaf_node; LoadLeafFromDisk(leaf_id, current_leaf_node); @@ -491,9 +507,8 @@ class StaticRTree projected_input_coordinate_fixed, projected_nearest); // distance must be non-negative BOOST_ASSERT(0. <= squared_distance); - traversal_queue.push( - QueryCandidate{squared_distance, CandidateSegment{Coordinate{projected_nearest}, - std::move(current_edge)}}); + traversal_queue.push(QueryCandidate{squared_distance, SegmentIndex {static_cast(candidate_cache.size())}}); + candidate_cache.push_back(CandidateSegment{Coordinate{projected_nearest}, std::move(current_edge)}); } } @@ -510,7 +525,7 @@ class StaticRTree const auto squared_lower_bound_to_element = child_rectangle.GetMinSquaredDist(fixed_projected_input_coordinate); traversal_queue.push( - QueryCandidate{squared_lower_bound_to_element, child_id}); + QueryCandidate{squared_lower_bound_to_element, TreeIndex{static_cast(child_id)}}); } }