itroduce ADL via algorithm specific ch, corech and mld namespaces

This commit is contained in:
Michael Krasnyk
2017-03-31 12:52:04 +02:00
parent 2566f64c34
commit 8c64b01d67
23 changed files with 501 additions and 464 deletions
+237 -236
View File
@@ -16,7 +16,7 @@ namespace ch
* @param to the node the CH edge finishes at
* @param unpacked_path the sequence of original NodeIDs that make up the expanded CH edge
*/
void unpackEdge(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
void unpackEdge(const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
const NodeID from,
const NodeID to,
std::vector<NodeID> &unpacked_path)
@@ -71,7 +71,7 @@ void retrievePackedPathFromSingleHeap(const SearchEngineData::QueryHeap &search_
// && source_phantom.GetForwardWeightPlusOffset() > target_phantom.GetForwardWeightPlusOffset())
// requires
// a force loop, if the heaps have been initialized with positive offsets.
void search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
void search(const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
SearchEngineData::QueryHeap &forward_heap,
SearchEngineData::QueryHeap &reverse_heap,
EdgeWeight &weight,
@@ -139,190 +139,6 @@ void search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH>
}
}
// assumes that heaps are already setup correctly.
// A forced loop might be necessary, if source and target are on the same segment.
// If this is the case and the offsets of the respective direction are larger for the source
// than the target
// then a force loop is required (e.g. source_phantom.forward_segment_id ==
// target_phantom.forward_segment_id
// && source_phantom.GetForwardWeightPlusOffset() > target_phantom.GetForwardWeightPlusOffset())
// requires
// a force loop, if the heaps have been initialized with positive offsets.
void search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CoreCH> &facade,
SearchEngineData::QueryHeap &forward_heap,
SearchEngineData::QueryHeap &reverse_heap,
SearchEngineData::QueryHeap &forward_core_heap,
SearchEngineData::QueryHeap &reverse_core_heap,
EdgeWeight &weight,
std::vector<NodeID> &packed_leg,
const bool force_loop_forward,
const bool force_loop_reverse,
EdgeWeight weight_upper_bound)
{
NodeID middle = SPECIAL_NODEID;
weight = weight_upper_bound;
using CoreEntryPoint = std::tuple<NodeID, EdgeWeight, NodeID>;
std::vector<CoreEntryPoint> forward_entry_points;
std::vector<CoreEntryPoint> reverse_entry_points;
// get offset to account for offsets on phantom nodes on compressed edges
const auto min_edge_offset = std::min(0, forward_heap.MinKey());
// we only every insert negative offsets for nodes in the forward heap
BOOST_ASSERT(reverse_heap.MinKey() >= 0);
// run two-Target Dijkstra routing step.
while (0 < (forward_heap.Size() + reverse_heap.Size()))
{
if (!forward_heap.Empty())
{
if (facade.IsCoreNode(forward_heap.Min()))
{
const NodeID node = forward_heap.DeleteMin();
const EdgeWeight key = forward_heap.GetKey(node);
forward_entry_points.emplace_back(node, key, forward_heap.GetData(node).parent);
}
else
{
routingStep<FORWARD_DIRECTION>(facade,
forward_heap,
reverse_heap,
middle,
weight,
min_edge_offset,
force_loop_forward,
force_loop_reverse);
}
}
if (!reverse_heap.Empty())
{
if (facade.IsCoreNode(reverse_heap.Min()))
{
const NodeID node = reverse_heap.DeleteMin();
const EdgeWeight key = reverse_heap.GetKey(node);
reverse_entry_points.emplace_back(node, key, reverse_heap.GetData(node).parent);
}
else
{
routingStep<REVERSE_DIRECTION>(facade,
reverse_heap,
forward_heap,
middle,
weight,
min_edge_offset,
force_loop_reverse,
force_loop_forward);
}
}
}
const auto insertInCoreHeap = [](const CoreEntryPoint &p,
SearchEngineData::QueryHeap &core_heap) {
NodeID id;
EdgeWeight weight;
NodeID parent;
// TODO this should use std::apply when we get c++17 support
std::tie(id, weight, parent) = p;
core_heap.Insert(id, weight, parent);
};
forward_core_heap.Clear();
for (const auto &p : forward_entry_points)
{
insertInCoreHeap(p, forward_core_heap);
}
reverse_core_heap.Clear();
for (const auto &p : reverse_entry_points)
{
insertInCoreHeap(p, reverse_core_heap);
}
// get offset to account for offsets on phantom nodes on compressed edges
EdgeWeight min_core_edge_offset = 0;
if (forward_core_heap.Size() > 0)
{
min_core_edge_offset = std::min(min_core_edge_offset, forward_core_heap.MinKey());
}
if (reverse_core_heap.Size() > 0 && reverse_core_heap.MinKey() < 0)
{
min_core_edge_offset = std::min(min_core_edge_offset, reverse_core_heap.MinKey());
}
BOOST_ASSERT(min_core_edge_offset <= 0);
// run two-target Dijkstra routing step on core with termination criterion
while (0 < forward_core_heap.Size() && 0 < reverse_core_heap.Size() &&
weight > (forward_core_heap.MinKey() + reverse_core_heap.MinKey()))
{
routingStep<FORWARD_DIRECTION, DISABLE_STALLING>(facade,
forward_core_heap,
reverse_core_heap,
middle,
weight,
min_core_edge_offset,
force_loop_forward,
force_loop_reverse);
routingStep<REVERSE_DIRECTION, DISABLE_STALLING>(facade,
reverse_core_heap,
forward_core_heap,
middle,
weight,
min_core_edge_offset,
force_loop_reverse,
force_loop_forward);
}
// No path found for both target nodes?
if (weight_upper_bound <= weight || SPECIAL_NODEID == middle)
{
weight = INVALID_EDGE_WEIGHT;
return;
}
// Was a paths over one of the forward/reverse nodes not found?
BOOST_ASSERT_MSG((SPECIAL_NODEID != middle && INVALID_EDGE_WEIGHT != weight), "no path found");
// we need to unpack sub path from core heaps
if (facade.IsCoreNode(middle))
{
if (weight != forward_core_heap.GetKey(middle) + reverse_core_heap.GetKey(middle))
{
// self loop
BOOST_ASSERT(forward_core_heap.GetData(middle).parent == middle &&
reverse_core_heap.GetData(middle).parent == middle);
packed_leg.push_back(middle);
packed_leg.push_back(middle);
}
else
{
std::vector<NodeID> packed_core_leg;
retrievePackedPathFromHeap(
forward_core_heap, reverse_core_heap, middle, packed_core_leg);
BOOST_ASSERT(packed_core_leg.size() > 0);
retrievePackedPathFromSingleHeap(forward_heap, packed_core_leg.front(), packed_leg);
std::reverse(packed_leg.begin(), packed_leg.end());
packed_leg.insert(packed_leg.end(), packed_core_leg.begin(), packed_core_leg.end());
retrievePackedPathFromSingleHeap(reverse_heap, packed_core_leg.back(), packed_leg);
}
}
else
{
if (weight != forward_heap.GetKey(middle) + reverse_heap.GetKey(middle))
{
// self loop
BOOST_ASSERT(forward_heap.GetData(middle).parent == middle &&
reverse_heap.GetData(middle).parent == middle);
packed_leg.push_back(middle);
packed_leg.push_back(middle);
}
else
{
retrievePackedPathFromHeap(forward_heap, reverse_heap, middle, packed_leg);
}
}
}
bool needsLoopForward(const PhantomNode &source_phantom, const PhantomNode &target_phantom)
{
return source_phantom.forward_segment_id.enabled && target_phantom.forward_segment_id.enabled &&
@@ -339,7 +155,7 @@ bool needsLoopBackwards(const PhantomNode &source_phantom, const PhantomNode &ta
target_phantom.GetReverseWeightPlusOffset();
}
double getPathDistance(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
double getPathDistance(const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
const std::vector<NodeID> &packed_path,
const PhantomNode &source_phantom,
const PhantomNode &target_phantom)
@@ -398,54 +214,12 @@ double getPathDistance(const datafacade::ContiguousInternalMemoryDataFacade<algo
// Requires the heaps for be empty
// If heaps should be adjusted to be initialized outside of this function,
// the addition of force_loop parameters might be required
double
getNetworkDistance(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CoreCH> &facade,
SearchEngineData::QueryHeap &forward_heap,
SearchEngineData::QueryHeap &reverse_heap,
SearchEngineData::QueryHeap &forward_core_heap,
SearchEngineData::QueryHeap &reverse_core_heap,
const PhantomNode &source_phantom,
const PhantomNode &target_phantom,
EdgeWeight weight_upper_bound)
{
forward_heap.Clear();
reverse_heap.Clear();
forward_core_heap.Clear();
reverse_core_heap.Clear();
insertNodesInHeaps(forward_heap, reverse_heap, {source_phantom, target_phantom});
EdgeWeight weight = INVALID_EDGE_WEIGHT;
std::vector<NodeID> packed_path;
search(facade,
forward_heap,
reverse_heap,
forward_core_heap,
reverse_core_heap,
weight,
packed_path,
DO_NOT_FORCE_LOOPS,
DO_NOT_FORCE_LOOPS,
weight_upper_bound);
double distance = std::numeric_limits<double>::max();
if (weight != INVALID_EDGE_WEIGHT)
{
return getPathDistance(facade, packed_path, source_phantom, target_phantom);
}
return distance;
}
// Requires the heaps for be empty
// If heaps should be adjusted to be initialized outside of this function,
// the addition of force_loop parameters might be required
double
getNetworkDistance(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
SearchEngineData::QueryHeap &forward_heap,
SearchEngineData::QueryHeap &reverse_heap,
const PhantomNode &source_phantom,
const PhantomNode &target_phantom,
EdgeWeight weight_upper_bound)
double getNetworkDistance(const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
SearchEngineData::QueryHeap &forward_heap,
SearchEngineData::QueryHeap &reverse_heap,
const PhantomNode &source_phantom,
const PhantomNode &target_phantom,
EdgeWeight weight_upper_bound)
{
forward_heap.Clear();
reverse_heap.Clear();
@@ -494,8 +268,235 @@ getNetworkDistance(const datafacade::ContiguousInternalMemoryDataFacade<algorith
return getPathDistance(facade, packed_path, source_phantom, target_phantom);
}
} // namespace ch
namespace corech
{
// Assumes that heaps are already setup correctly.
// A forced loop might be necessary, if source and target are on the same segment.
// If this is the case and the offsets of the respective direction are larger for the source
// than the target
// then a force loop is required (e.g. source_phantom.forward_segment_id ==
// target_phantom.forward_segment_id
// && source_phantom.GetForwardWeightPlusOffset() > target_phantom.GetForwardWeightPlusOffset())
// requires
// a force loop, if the heaps have been initialized with positive offsets.
void search(const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
SearchEngineData::QueryHeap &forward_heap,
SearchEngineData::QueryHeap &reverse_heap,
SearchEngineData::QueryHeap &forward_core_heap,
SearchEngineData::QueryHeap &reverse_core_heap,
EdgeWeight &weight,
std::vector<NodeID> &packed_leg,
const bool force_loop_forward,
const bool force_loop_reverse,
EdgeWeight weight_upper_bound)
{
NodeID middle = SPECIAL_NODEID;
weight = weight_upper_bound;
using CoreEntryPoint = std::tuple<NodeID, EdgeWeight, NodeID>;
std::vector<CoreEntryPoint> forward_entry_points;
std::vector<CoreEntryPoint> reverse_entry_points;
// get offset to account for offsets on phantom nodes on compressed edges
const auto min_edge_offset = std::min(0, forward_heap.MinKey());
// we only every insert negative offsets for nodes in the forward heap
BOOST_ASSERT(reverse_heap.MinKey() >= 0);
// run two-Target Dijkstra routing step.
while (0 < (forward_heap.Size() + reverse_heap.Size()))
{
if (!forward_heap.Empty())
{
if (facade.IsCoreNode(forward_heap.Min()))
{
const NodeID node = forward_heap.DeleteMin();
const EdgeWeight key = forward_heap.GetKey(node);
forward_entry_points.emplace_back(node, key, forward_heap.GetData(node).parent);
}
else
{
ch::routingStep<FORWARD_DIRECTION>(facade,
forward_heap,
reverse_heap,
middle,
weight,
min_edge_offset,
force_loop_forward,
force_loop_reverse);
}
}
if (!reverse_heap.Empty())
{
if (facade.IsCoreNode(reverse_heap.Min()))
{
const NodeID node = reverse_heap.DeleteMin();
const EdgeWeight key = reverse_heap.GetKey(node);
reverse_entry_points.emplace_back(node, key, reverse_heap.GetData(node).parent);
}
else
{
ch::routingStep<REVERSE_DIRECTION>(facade,
reverse_heap,
forward_heap,
middle,
weight,
min_edge_offset,
force_loop_reverse,
force_loop_forward);
}
}
}
const auto insertInCoreHeap = [](const CoreEntryPoint &p,
SearchEngineData::QueryHeap &core_heap) {
NodeID id;
EdgeWeight weight;
NodeID parent;
// TODO this should use std::apply when we get c++17 support
std::tie(id, weight, parent) = p;
core_heap.Insert(id, weight, parent);
};
forward_core_heap.Clear();
for (const auto &p : forward_entry_points)
{
insertInCoreHeap(p, forward_core_heap);
}
reverse_core_heap.Clear();
for (const auto &p : reverse_entry_points)
{
insertInCoreHeap(p, reverse_core_heap);
}
// get offset to account for offsets on phantom nodes on compressed edges
EdgeWeight min_core_edge_offset = 0;
if (forward_core_heap.Size() > 0)
{
min_core_edge_offset = std::min(min_core_edge_offset, forward_core_heap.MinKey());
}
if (reverse_core_heap.Size() > 0 && reverse_core_heap.MinKey() < 0)
{
min_core_edge_offset = std::min(min_core_edge_offset, reverse_core_heap.MinKey());
}
BOOST_ASSERT(min_core_edge_offset <= 0);
// run two-target Dijkstra routing step on core with termination criterion
while (0 < forward_core_heap.Size() && 0 < reverse_core_heap.Size() &&
weight > (forward_core_heap.MinKey() + reverse_core_heap.MinKey()))
{
ch::routingStep<FORWARD_DIRECTION, ch::DISABLE_STALLING>(facade,
forward_core_heap,
reverse_core_heap,
middle,
weight,
min_core_edge_offset,
force_loop_forward,
force_loop_reverse);
ch::routingStep<REVERSE_DIRECTION, ch::DISABLE_STALLING>(facade,
reverse_core_heap,
forward_core_heap,
middle,
weight,
min_core_edge_offset,
force_loop_reverse,
force_loop_forward);
}
// No path found for both target nodes?
if (weight_upper_bound <= weight || SPECIAL_NODEID == middle)
{
weight = INVALID_EDGE_WEIGHT;
return;
}
// Was a paths over one of the forward/reverse nodes not found?
BOOST_ASSERT_MSG((SPECIAL_NODEID != middle && INVALID_EDGE_WEIGHT != weight), "no path found");
// we need to unpack sub path from core heaps
if (facade.IsCoreNode(middle))
{
if (weight != forward_core_heap.GetKey(middle) + reverse_core_heap.GetKey(middle))
{
// self loop
BOOST_ASSERT(forward_core_heap.GetData(middle).parent == middle &&
reverse_core_heap.GetData(middle).parent == middle);
packed_leg.push_back(middle);
packed_leg.push_back(middle);
}
else
{
std::vector<NodeID> packed_core_leg;
ch::retrievePackedPathFromHeap(
forward_core_heap, reverse_core_heap, middle, packed_core_leg);
BOOST_ASSERT(packed_core_leg.size() > 0);
ch::retrievePackedPathFromSingleHeap(forward_heap, packed_core_leg.front(), packed_leg);
std::reverse(packed_leg.begin(), packed_leg.end());
packed_leg.insert(packed_leg.end(), packed_core_leg.begin(), packed_core_leg.end());
ch::retrievePackedPathFromSingleHeap(reverse_heap, packed_core_leg.back(), packed_leg);
}
}
else
{
if (weight != forward_heap.GetKey(middle) + reverse_heap.GetKey(middle))
{
// self loop
BOOST_ASSERT(forward_heap.GetData(middle).parent == middle &&
reverse_heap.GetData(middle).parent == middle);
packed_leg.push_back(middle);
packed_leg.push_back(middle);
}
else
{
ch::retrievePackedPathFromHeap(forward_heap, reverse_heap, middle, packed_leg);
}
}
}
// Requires the heaps for be empty
// If heaps should be adjusted to be initialized outside of this function,
// the addition of force_loop parameters might be required
double getNetworkDistance(const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
SearchEngineData::QueryHeap &forward_heap,
SearchEngineData::QueryHeap &reverse_heap,
SearchEngineData::QueryHeap &forward_core_heap,
SearchEngineData::QueryHeap &reverse_core_heap,
const PhantomNode &source_phantom,
const PhantomNode &target_phantom,
EdgeWeight weight_upper_bound)
{
forward_heap.Clear();
reverse_heap.Clear();
forward_core_heap.Clear();
reverse_core_heap.Clear();
insertNodesInHeaps(forward_heap, reverse_heap, {source_phantom, target_phantom});
EdgeWeight weight = INVALID_EDGE_WEIGHT;
std::vector<NodeID> packed_path;
search(facade,
forward_heap,
reverse_heap,
forward_core_heap,
reverse_core_heap,
weight,
packed_path,
DO_NOT_FORCE_LOOPS,
DO_NOT_FORCE_LOOPS,
weight_upper_bound);
double distance = std::numeric_limits<double>::max();
if (weight != INVALID_EDGE_WEIGHT)
{
return ch::getPathDistance(facade, packed_path, source_phantom, target_phantom);
}
return distance;
}
} // namespace corech
} // namespace routing_algorithms
} // namespace engine
} // namespace osrm