Avoid dynamic binding in getNodeQureyLevel

This commit is contained in:
Michael Krasnyk 2017-03-16 07:52:17 +01:00
parent 0c6ce6ce08
commit f1b88adebe
No known key found for this signature in database
GPG Key ID: 49C12AD0F43D2108
2 changed files with 35 additions and 36 deletions

View File

@ -21,17 +21,38 @@ namespace mld
namespace namespace
{ {
// Unrestricted search (Args is std::function<LevelID(const NodeID)>): // Unrestricted search (Args is const PhantomNodes &):
// * use `query_level` closure of partition.GetQueryLevel to find the query level // * use partition.GetQueryLevel to find the node query level based on source and target phantoms
// * allow to traverse all cells // * allow to traverse all cells
using QueryLevelFunction = std::function<LevelID(const NodeID)>; LevelID getNodeQureyLevel(const partition::MultiLevelPartitionView &partition,
LevelID getNodeQureyLevel(NodeID node, const QueryLevelFunction &functor) { return functor(node); } NodeID node,
bool checkParentCellRestriction(CellID, const QueryLevelFunction &) { return true; } const PhantomNodes &phantom_nodes)
{
auto level = [&partition, node](const SegmentID &source, const SegmentID &target) {
if (source.enabled && target.enabled)
return partition.GetQueryLevel(source.id, target.id, node);
return INVALID_LEVEL_ID;
};
return std::min(std::min(level(phantom_nodes.source_phantom.forward_segment_id,
phantom_nodes.target_phantom.forward_segment_id),
level(phantom_nodes.source_phantom.forward_segment_id,
phantom_nodes.target_phantom.reverse_segment_id)),
std::min(level(phantom_nodes.source_phantom.reverse_segment_id,
phantom_nodes.target_phantom.forward_segment_id),
level(phantom_nodes.source_phantom.reverse_segment_id,
phantom_nodes.target_phantom.reverse_segment_id)));
}
bool checkParentCellRestriction(CellID, const PhantomNodes &) { return true; }
// Restricted search (Args is LevelID, CellID): // Restricted search (Args is LevelID, CellID):
// * use the fixed level for queries // * use the fixed level for queries
// * check if the node cell is the same as the specified parent onr // * check if the node cell is the same as the specified parent onr
LevelID getNodeQureyLevel(NodeID, LevelID level, CellID) { return level; } LevelID getNodeQureyLevel(const partition::MultiLevelPartitionView &, NodeID, LevelID level, CellID)
{
return level;
}
bool checkParentCellRestriction(CellID cell, LevelID, CellID parent) { return cell == parent; } bool checkParentCellRestriction(CellID cell, LevelID, CellID parent) { return cell == parent; }
} }
@ -65,7 +86,7 @@ void routingStep(const datafacade::ContiguousInternalMemoryDataFacade<algorithm:
} }
} }
const auto level = getNodeQureyLevel(node, args...); const auto level = getNodeQureyLevel(partition, node, args...);
const auto &node_data = forward_heap.GetData(node); const auto &node_data = forward_heap.GetData(node);
const auto check_overlay_edges = const auto check_overlay_edges =
(level >= 1) && // only if at least the first level and (level >= 1) && // only if at least the first level and
@ -155,7 +176,8 @@ void routingStep(const datafacade::ContiguousInternalMemoryDataFacade<algorithm:
} }
template <typename... Args> template <typename... Args>
auto search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::MLD> &facade, std::tuple<EdgeWeight, NodeID, NodeID, std::vector<EdgeID>>
search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::MLD> &facade,
SearchEngineData::MultiLayerDijkstraHeap &forward_heap, SearchEngineData::MultiLayerDijkstraHeap &forward_heap,
SearchEngineData::MultiLayerDijkstraHeap &reverse_heap, SearchEngineData::MultiLayerDijkstraHeap &reverse_heap,
Args... args) Args... args)
@ -234,7 +256,7 @@ auto search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::MLD>
} }
else else
{ // an overlay graph edge { // an overlay graph edge
LevelID level = getNodeQureyLevel(source, args...); LevelID level = getNodeQureyLevel(partition, source, args...);
CellID parent_cell_id = partition.GetCell(level, source); CellID parent_cell_id = partition.GetCell(level, source);
BOOST_ASSERT(parent_cell_id == partition.GetCell(level, target)); BOOST_ASSERT(parent_cell_id == partition.GetCell(level, target));

View File

@ -138,36 +138,13 @@ InternalRouteResult directShortestPathSearch(
reverse_heap.Clear(); reverse_heap.Clear();
insertNodesInHeaps(forward_heap, reverse_heap, phantom_nodes); insertNodesInHeaps(forward_heap, reverse_heap, phantom_nodes);
const auto &partition = facade.GetMultiLevelPartition();
auto get_query_level = [&partition, &phantom_nodes](const NodeID node) -> LevelID {
auto level =
[&partition](const SegmentID &source, const SegmentID &target, const NodeID node) {
if (source.enabled && target.enabled)
return partition.GetQueryLevel(source.id, target.id, node);
return INVALID_LEVEL_ID;
};
return std::min(std::min(level(phantom_nodes.source_phantom.forward_segment_id,
phantom_nodes.target_phantom.forward_segment_id,
node),
level(phantom_nodes.source_phantom.forward_segment_id,
phantom_nodes.target_phantom.reverse_segment_id,
node)),
std::min(level(phantom_nodes.source_phantom.reverse_segment_id,
phantom_nodes.target_phantom.forward_segment_id,
node),
level(phantom_nodes.source_phantom.reverse_segment_id,
phantom_nodes.target_phantom.reverse_segment_id,
node)));
};
// TODO: when structured bindings will be allowed change to // TODO: when structured bindings will be allowed change to
// auto [weight, source_node, target_node, unpacked_edges] = ... // auto [weight, source_node, target_node, unpacked_edges] = ...
EdgeWeight weight; EdgeWeight weight;
NodeID source_node, target_node; NodeID source_node, target_node;
std::vector<EdgeID> unpacked_edges; std::vector<EdgeID> unpacked_edges;
std::tie(weight, source_node, target_node, unpacked_edges) = std::tie(weight, source_node, target_node, unpacked_edges) =
mld::search(facade, forward_heap, reverse_heap, get_query_level); mld::search(facade, forward_heap, reverse_heap, phantom_nodes);
return extractRoute(facade, weight, source_node, target_node, unpacked_edges, phantom_nodes); return extractRoute(facade, weight, source_node, target_node, unpacked_edges, phantom_nodes);
} }