Change size of QueryCandidate from 32 to 24 bytes
This commit is contained in:
parent
3e5c978719
commit
371c06d66d
@ -22,8 +22,6 @@
|
|||||||
#include <tbb/parallel_for.h>
|
#include <tbb/parallel_for.h>
|
||||||
#include <tbb/parallel_sort.h>
|
#include <tbb/parallel_sort.h>
|
||||||
|
|
||||||
#include <variant/variant.hpp>
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
@ -72,10 +70,10 @@ class StaticRTree
|
|||||||
EdgeDataT data;
|
EdgeDataT data;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TreeNodeIndex
|
struct TreeIndex
|
||||||
{
|
{
|
||||||
TreeNodeIndex() : index(0), is_leaf(false) {}
|
TreeIndex() : index(0), is_leaf(false) {}
|
||||||
TreeNodeIndex(std::size_t index, bool is_leaf) : index(index), is_leaf(is_leaf) {}
|
TreeIndex(std::size_t index, bool is_leaf) : index(index), is_leaf(is_leaf) {}
|
||||||
std::uint32_t index : 31;
|
std::uint32_t index : 31;
|
||||||
std::uint32_t is_leaf : 1;
|
std::uint32_t is_leaf : 1;
|
||||||
};
|
};
|
||||||
@ -85,7 +83,7 @@ class StaticRTree
|
|||||||
TreeNode() : child_count(0) {}
|
TreeNode() : child_count(0) {}
|
||||||
std::uint32_t child_count;
|
std::uint32_t child_count;
|
||||||
Rectangle minimum_bounding_rectangle;
|
Rectangle minimum_bounding_rectangle;
|
||||||
TreeNodeIndex children[BRANCHING_FACTOR];
|
TreeIndex children[BRANCHING_FACTOR];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ALIGNED(LEAF_PAGE_SIZE) LeafNode
|
struct ALIGNED(LEAF_PAGE_SIZE) LeafNode
|
||||||
@ -116,11 +114,27 @@ class StaticRTree
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TreeIndex {};
|
|
||||||
struct SegmentIndex { std::uint32_t object; Coordinate fixed_projected_coordinate; };
|
|
||||||
using QueryNodeType = mapbox::util::variant<TreeIndex, SegmentIndex>;
|
|
||||||
struct QueryCandidate
|
struct QueryCandidate
|
||||||
{
|
{
|
||||||
|
QueryCandidate(std::uint64_t squared_min_dist, TreeIndex tree_index)
|
||||||
|
: squared_min_dist(squared_min_dist)
|
||||||
|
, tree_index(tree_index)
|
||||||
|
, segment_index(std::numeric_limits<std::uint32_t>::max())
|
||||||
|
{}
|
||||||
|
|
||||||
|
QueryCandidate(std::uint64_t squared_min_dist, TreeIndex tree_index,
|
||||||
|
std::uint32_t segment_index, const Coordinate& coordinate)
|
||||||
|
: squared_min_dist(squared_min_dist)
|
||||||
|
, tree_index(tree_index)
|
||||||
|
, segment_index(segment_index)
|
||||||
|
, fixed_projected_coordinate(coordinate)
|
||||||
|
{}
|
||||||
|
|
||||||
|
inline bool is_segment() const
|
||||||
|
{
|
||||||
|
return segment_index != std::numeric_limits<std::uint32_t>::max();
|
||||||
|
}
|
||||||
|
|
||||||
inline bool operator<(const QueryCandidate &other) const
|
inline bool operator<(const QueryCandidate &other) const
|
||||||
{
|
{
|
||||||
// Attn: this is reversed order. std::pq is a max pq!
|
// Attn: this is reversed order. std::pq is a max pq!
|
||||||
@ -128,8 +142,9 @@ class StaticRTree
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::uint64_t squared_min_dist;
|
std::uint64_t squared_min_dist;
|
||||||
TreeNodeIndex index;
|
TreeIndex tree_index;
|
||||||
QueryNodeType node;
|
std::uint32_t segment_index;
|
||||||
|
Coordinate fixed_projected_coordinate;
|
||||||
};
|
};
|
||||||
|
|
||||||
typename ShM<TreeNode, UseSharedMemory>::vector m_search_tree;
|
typename ShM<TreeNode, UseSharedMemory>::vector m_search_tree;
|
||||||
@ -185,7 +200,7 @@ class StaticRTree
|
|||||||
tbb::parallel_sort(input_wrapper_vector.begin(), input_wrapper_vector.end());
|
tbb::parallel_sort(input_wrapper_vector.begin(), input_wrapper_vector.end());
|
||||||
std::vector<TreeNode> tree_nodes_in_level;
|
std::vector<TreeNode> tree_nodes_in_level;
|
||||||
|
|
||||||
// pack M elements into leaf node and write to leaf file
|
// pack M elements into leaf node, write to leaf file and append a child index to the parent tree node
|
||||||
uint64_t wrapped_element_index = 0;
|
uint64_t wrapped_element_index = 0;
|
||||||
for (std::uint32_t node_index = 0; wrapped_element_index < element_count; ++node_index)
|
for (std::uint32_t node_index = 0; wrapped_element_index < element_count; ++node_index)
|
||||||
{
|
{
|
||||||
@ -225,7 +240,7 @@ class StaticRTree
|
|||||||
|
|
||||||
// append the leaf node to the current tree node
|
// append the leaf node to the current tree node
|
||||||
current_node.child_count += 1;
|
current_node.child_count += 1;
|
||||||
current_node.children[leaf_index] = TreeNodeIndex{node_index * BRANCHING_FACTOR + leaf_index, true};
|
current_node.children[leaf_index] = TreeIndex{node_index * BRANCHING_FACTOR + leaf_index, true};
|
||||||
current_node.minimum_bounding_rectangle.MergeBoundingBoxes(current_leaf.minimum_bounding_rectangle);
|
current_node.minimum_bounding_rectangle.MergeBoundingBoxes(current_leaf.minimum_bounding_rectangle);
|
||||||
|
|
||||||
// write leaf_node to leaf node file
|
// write leaf_node to leaf node file
|
||||||
@ -253,7 +268,7 @@ class StaticRTree
|
|||||||
{
|
{
|
||||||
TreeNode ¤t_child_node = tree_nodes_in_level[processed_tree_nodes_in_level];
|
TreeNode ¤t_child_node = tree_nodes_in_level[processed_tree_nodes_in_level];
|
||||||
// add tree node to parent entry
|
// add tree node to parent entry
|
||||||
parent_node.children[current_child_node_index] = TreeNodeIndex{m_search_tree.size(), false};
|
parent_node.children[current_child_node_index] = TreeIndex{m_search_tree.size(), false};
|
||||||
m_search_tree.emplace_back(current_child_node);
|
m_search_tree.emplace_back(current_child_node);
|
||||||
// merge MBRs
|
// merge MBRs
|
||||||
parent_node.minimum_bounding_rectangle.MergeBoundingBoxes(
|
parent_node.minimum_bounding_rectangle.MergeBoundingBoxes(
|
||||||
@ -367,8 +382,8 @@ class StaticRTree
|
|||||||
toFixed(FloatLatitude{web_mercator::latToY(toFloating(FixedLatitude(search_rectangle.max_lat)))})};
|
toFixed(FloatLatitude{web_mercator::latToY(toFloating(FixedLatitude(search_rectangle.max_lat)))})};
|
||||||
std::vector<EdgeDataT> results;
|
std::vector<EdgeDataT> results;
|
||||||
|
|
||||||
std::queue<TreeNodeIndex> traversal_queue;
|
std::queue<TreeIndex> traversal_queue;
|
||||||
traversal_queue.push(TreeNodeIndex{});
|
traversal_queue.push(TreeIndex{});
|
||||||
|
|
||||||
while (!traversal_queue.empty())
|
while (!traversal_queue.empty())
|
||||||
{
|
{
|
||||||
@ -406,7 +421,7 @@ class StaticRTree
|
|||||||
// to the search queue if their bounding boxes intersect
|
// to the search queue if their bounding boxes intersect
|
||||||
for (std::uint32_t i = 0; i < current_tree_node.child_count; ++i)
|
for (std::uint32_t i = 0; i < current_tree_node.child_count; ++i)
|
||||||
{
|
{
|
||||||
const TreeNodeIndex child_id = current_tree_node.children[i];
|
const TreeIndex child_id = current_tree_node.children[i];
|
||||||
const auto &child_rectangle = child_id.is_leaf
|
const auto &child_rectangle = child_id.is_leaf
|
||||||
? m_leaves[child_id.index].minimum_bounding_rectangle
|
? m_leaves[child_id.index].minimum_bounding_rectangle
|
||||||
: m_search_tree[child_id.index].minimum_bounding_rectangle;
|
: m_search_tree[child_id.index].minimum_bounding_rectangle;
|
||||||
@ -443,15 +458,15 @@ 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, TreeNodeIndex{}, TreeIndex{}});
|
traversal_queue.push(QueryCandidate{0, TreeIndex{}});
|
||||||
|
|
||||||
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();
|
||||||
|
|
||||||
const TreeNodeIndex ¤t_tree_index = current_query_node.index;
|
const TreeIndex ¤t_tree_index = current_query_node.tree_index;
|
||||||
if (current_query_node.node.template is<TreeIndex>())
|
if (!current_query_node.is_segment())
|
||||||
{ // current object is a tree node
|
{ // current object is a tree node
|
||||||
if (current_tree_index.is_leaf)
|
if (current_tree_index.is_leaf)
|
||||||
{
|
{
|
||||||
@ -464,9 +479,8 @@ class StaticRTree
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // current candidate is an actual road segment
|
{ // current candidate is an actual road segment
|
||||||
const auto &segment_index = current_query_node.node.template get<SegmentIndex>();
|
auto edge_data = m_leaves[current_tree_index.index].objects[current_query_node.segment_index];
|
||||||
auto edge_data = m_leaves[current_tree_index.index].objects[segment_index.object];
|
const auto ¤t_candidate = CandidateSegment{current_query_node.fixed_projected_coordinate, edge_data};
|
||||||
const auto ¤t_candidate = CandidateSegment{segment_index.fixed_projected_coordinate, edge_data};
|
|
||||||
|
|
||||||
// to allow returns of no-results if too restrictive filtering, this needs to be
|
// to allow returns of no-results if too restrictive filtering, this needs to be
|
||||||
// done here
|
// done here
|
||||||
@ -495,7 +509,7 @@ class StaticRTree
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename QueueT>
|
template <typename QueueT>
|
||||||
void ExploreLeafNode(const TreeNodeIndex &leaf_id,
|
void ExploreLeafNode(const TreeIndex &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) const
|
QueueT &traversal_queue) const
|
||||||
@ -517,25 +531,25 @@ class StaticRTree
|
|||||||
coordinate_calculation::squaredEuclideanDistance(projected_input_coordinate_fixed, projected_nearest);
|
coordinate_calculation::squaredEuclideanDistance(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(QueryCandidate{squared_distance, leaf_id, SegmentIndex{i, Coordinate{projected_nearest}}});
|
traversal_queue.push(QueryCandidate{squared_distance, leaf_id, i, Coordinate{projected_nearest}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class QueueT>
|
template <class QueueT>
|
||||||
void ExploreTreeNode(const TreeNodeIndex &parent_id,
|
void ExploreTreeNode(const TreeIndex &parent_id,
|
||||||
const Coordinate fixed_projected_input_coordinate,
|
const Coordinate fixed_projected_input_coordinate,
|
||||||
QueueT &traversal_queue) const
|
QueueT &traversal_queue) const
|
||||||
{
|
{
|
||||||
const TreeNode &parent = m_search_tree[parent_id.index];
|
const TreeNode &parent = m_search_tree[parent_id.index];
|
||||||
for (std::uint32_t i = 0; i < parent.child_count; ++i)
|
for (std::uint32_t i = 0; i < parent.child_count; ++i)
|
||||||
{
|
{
|
||||||
const TreeNodeIndex child_id = parent.children[i];
|
const TreeIndex child_id = parent.children[i];
|
||||||
const auto &child_rectangle = child_id.is_leaf
|
const auto &child_rectangle = child_id.is_leaf
|
||||||
? m_leaves[child_id.index].minimum_bounding_rectangle
|
? m_leaves[child_id.index].minimum_bounding_rectangle
|
||||||
: m_search_tree[child_id.index].minimum_bounding_rectangle;
|
: m_search_tree[child_id.index].minimum_bounding_rectangle;
|
||||||
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(QueryCandidate{squared_lower_bound_to_element, child_id, TreeIndex{}});
|
traversal_queue.push(QueryCandidate{squared_lower_bound_to_element, child_id});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user