Add cache for CandidateSegments to reduce heap worke even more
This commit is contained in:
parent
7357a8d42b
commit
9692be6f50
@ -43,7 +43,8 @@ template <class EdgeDataT,
|
|||||||
class CoordinateListT = std::vector<Coordinate>,
|
class CoordinateListT = std::vector<Coordinate>,
|
||||||
bool UseSharedMemory = false,
|
bool UseSharedMemory = false,
|
||||||
std::uint32_t BRANCHING_FACTOR = 64,
|
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
|
class StaticRTree
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -93,7 +94,9 @@ class StaticRTree
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
using QueryNodeType = mapbox::util::variant<std::uint32_t, CandidateSegment>;
|
struct TreeIndex { std::uint32_t index; };
|
||||||
|
struct SegmentIndex { std::uint32_t index; };
|
||||||
|
using QueryNodeType = mapbox::util::variant<TreeIndex, SegmentIndex>;
|
||||||
struct QueryCandidate
|
struct QueryCandidate
|
||||||
{
|
{
|
||||||
inline bool operator<(const QueryCandidate &other) const
|
inline bool operator<(const QueryCandidate &other) const
|
||||||
@ -415,21 +418,26 @@ class StaticRTree
|
|||||||
|
|
||||||
// initialize queue with root element
|
// initialize queue with root element
|
||||||
std::priority_queue<QueryCandidate> traversal_queue;
|
std::priority_queue<QueryCandidate> 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<CandidateSegment> candidate_cache;
|
||||||
|
candidate_cache.reserve(LEAF_NODE_SIZE);
|
||||||
|
|
||||||
while (!traversal_queue.empty())
|
while (!traversal_queue.empty())
|
||||||
{
|
{
|
||||||
QueryCandidate current_query_node = traversal_queue.top();
|
QueryCandidate current_query_node = traversal_queue.top();
|
||||||
traversal_queue.pop();
|
traversal_queue.pop();
|
||||||
|
|
||||||
if (current_query_node.node.template is<std::uint32_t>())
|
if (current_query_node.node.template is<TreeIndex>())
|
||||||
{ // current object is a tree node
|
{ // current object is a tree node
|
||||||
const TreeNode ¤t_tree_node =
|
const TreeNode ¤t_tree_node =
|
||||||
m_search_tree[current_query_node.node.template get<std::uint32_t>()];
|
m_search_tree[current_query_node.node.template get<TreeIndex>().index];
|
||||||
if (current_tree_node.child_is_on_disk)
|
if (current_tree_node.child_is_on_disk)
|
||||||
{
|
{
|
||||||
ExploreLeafNode(current_tree_node.children[0], fixed_projected_coordinate,
|
ExploreLeafNode(current_tree_node.children[0], fixed_projected_coordinate,
|
||||||
projected_coordinate, traversal_queue);
|
projected_coordinate, traversal_queue, candidate_cache);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -439,7 +447,7 @@ class StaticRTree
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// inspecting an actual road segment
|
// inspecting an actual road segment
|
||||||
auto ¤t_candidate = current_query_node.node.template get<CandidateSegment>();
|
auto ¤t_candidate = candidate_cache[current_query_node.node.template get<SegmentIndex>().index];
|
||||||
|
|
||||||
// to allow returns of no-results if too restrictive filtering, this needs to be done here
|
// 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
|
// 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,
|
void ExploreLeafNode(const std::uint32_t leaf_id,
|
||||||
const Coordinate projected_input_coordinate_fixed,
|
const Coordinate projected_input_coordinate_fixed,
|
||||||
const FloatCoordinate &projected_input_coordinate,
|
const FloatCoordinate &projected_input_coordinate,
|
||||||
QueueT &traversal_queue)
|
QueueT &traversal_queue,
|
||||||
|
std::vector<CandidateSegment> &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;
|
LeafNode current_leaf_node;
|
||||||
LoadLeafFromDisk(leaf_id, current_leaf_node);
|
LoadLeafFromDisk(leaf_id, current_leaf_node);
|
||||||
|
|
||||||
@ -491,9 +507,8 @@ class StaticRTree
|
|||||||
projected_input_coordinate_fixed, projected_nearest);
|
projected_input_coordinate_fixed, projected_nearest);
|
||||||
// distance must be non-negative
|
// distance must be non-negative
|
||||||
BOOST_ASSERT(0. <= squared_distance);
|
BOOST_ASSERT(0. <= squared_distance);
|
||||||
traversal_queue.push(
|
traversal_queue.push(QueryCandidate{squared_distance, SegmentIndex {static_cast<std::uint32_t>(candidate_cache.size())}});
|
||||||
QueryCandidate{squared_distance, CandidateSegment{Coordinate{projected_nearest},
|
candidate_cache.push_back(CandidateSegment{Coordinate{projected_nearest}, std::move(current_edge)});
|
||||||
std::move(current_edge)}});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -510,7 +525,7 @@ class StaticRTree
|
|||||||
const auto squared_lower_bound_to_element =
|
const auto squared_lower_bound_to_element =
|
||||||
child_rectangle.GetMinSquaredDist(fixed_projected_input_coordinate);
|
child_rectangle.GetMinSquaredDist(fixed_projected_input_coordinate);
|
||||||
traversal_queue.push(
|
traversal_queue.push(
|
||||||
QueryCandidate{squared_lower_bound_to_element, child_id});
|
QueryCandidate{squared_lower_bound_to_element, TreeIndex{static_cast<std::uint32_t>(child_id)}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user