Implement CoreCH algorithm

This commit is contained in:
Patrick Niklaus 2017-02-25 05:13:38 +00:00 committed by Patrick Niklaus
parent 922e155763
commit 7da86b5984
19 changed files with 562 additions and 300 deletions

View File

@ -11,29 +11,75 @@ namespace algorithm
{ {
// Contraction Hiearchy // Contraction Hiearchy
struct CH final {}; struct CH final
{
};
// Contraction Hiearchy with core // Contraction Hiearchy with core
struct CoreCH final {}; struct CoreCH final
{
};
} }
namespace algorithm_trais namespace algorithm_trais
{ {
template <typename AlgorithmT> struct HasAlternativePathSearch final : std::false_type {}; template <typename AlgorithmT> struct HasAlternativePathSearch final : std::false_type
template <typename AlgorithmT> struct HasShortestPathSearch final : std::false_type {}; {
template <typename AlgorithmT> struct HasDirectShortestPathSearch final : std::false_type {}; };
template <typename AlgorithmT> struct HasMapMatching final : std::false_type {}; template <typename AlgorithmT> struct HasShortestPathSearch final : std::false_type
template <typename AlgorithmT> struct HasManyToManySearch final : std::false_type {}; {
template <typename AlgorithmT> struct HasGetTileTurns final : std::false_type {}; };
template <typename AlgorithmT> struct HasDirectShortestPathSearch final : std::false_type
{
};
template <typename AlgorithmT> struct HasMapMatching final : std::false_type
{
};
template <typename AlgorithmT> struct HasManyToManySearch final : std::false_type
{
};
template <typename AlgorithmT> struct HasGetTileTurns final : std::false_type
{
};
template <> struct HasAlternativePathSearch<algorithm::CH> final : std::true_type {}; template <> struct HasAlternativePathSearch<algorithm::CH> final : std::true_type
template <> struct HasShortestPathSearch<algorithm::CH> final : std::true_type {}; {
template <> struct HasDirectShortestPathSearch<algorithm::CH> final : std::true_type {}; };
template <> struct HasMapMatching<algorithm::CH> final : std::true_type {}; template <> struct HasShortestPathSearch<algorithm::CH> final : std::true_type
template <> struct HasManyToManySearch<algorithm::CH> final : std::true_type {}; {
template <> struct HasGetTileTurns<algorithm::CH> final : std::true_type {}; };
template <> struct HasDirectShortestPathSearch<algorithm::CH> final : std::true_type
{
};
template <> struct HasMapMatching<algorithm::CH> final : std::true_type
{
};
template <> struct HasManyToManySearch<algorithm::CH> final : std::true_type
{
};
template <> struct HasGetTileTurns<algorithm::CH> final : std::true_type
{
};
// disbaled because of perfomance reasons
template <> struct HasAlternativePathSearch<algorithm::CoreCH> final : std::false_type
{
};
template <> struct HasManyToManySearch<algorithm::CoreCH> final : std::false_type
{
};
template <> struct HasShortestPathSearch<algorithm::CoreCH> final : std::true_type
{
};
template <> struct HasDirectShortestPathSearch<algorithm::CoreCH> final : std::true_type
{
};
template <> struct HasMapMatching<algorithm::CoreCH> final : std::true_type
{
};
template <> struct HasGetTileTurns<algorithm::CoreCH> final : std::true_type
{
};
} }
} }
} }

View File

@ -49,6 +49,12 @@ template <> class AlgorithmDataFacade<algorithm::CH>
virtual EdgeID FindSmallestEdge(const NodeID from, virtual EdgeID FindSmallestEdge(const NodeID from,
const NodeID to, const NodeID to,
const std::function<bool(EdgeData)> filter) const = 0; const std::function<bool(EdgeData)> filter) const = 0;
};
template <> class AlgorithmDataFacade<algorithm::CoreCH>
{
public:
using EdgeData = contractor::QueryEdge::EdgeData;
virtual bool IsCoreNode(const NodeID id) const = 0; virtual bool IsCoreNode(const NodeID id) const = 0;

View File

@ -58,7 +58,6 @@ class ContiguousInternalMemoryAlgorithmDataFacade<algorithm::CH>
using GraphEdge = QueryGraph::EdgeArrayEntry; using GraphEdge = QueryGraph::EdgeArrayEntry;
std::unique_ptr<QueryGraph> m_query_graph; std::unique_ptr<QueryGraph> m_query_graph;
util::ShM<bool, true>::vector m_is_core_node;
// allocator that keeps the allocation data // allocator that keeps the allocation data
std::shared_ptr<ContiguousBlockAllocator> allocator; std::shared_ptr<ContiguousBlockAllocator> allocator;
@ -78,15 +77,6 @@ class ContiguousInternalMemoryAlgorithmDataFacade<algorithm::CH>
m_query_graph.reset(new QueryGraph(node_list, edge_list)); m_query_graph.reset(new QueryGraph(node_list, edge_list));
} }
void InitializeCoreInformationPointer(storage::DataLayout &data_layout, char *memory_block)
{
auto core_marker_ptr =
data_layout.GetBlockPtr<unsigned>(memory_block, storage::DataLayout::CH_CORE_MARKER);
util::ShM<bool, true>::vector is_core_node(
core_marker_ptr, data_layout.num_entries[storage::DataLayout::CH_CORE_MARKER]);
m_is_core_node = std::move(is_core_node);
}
public: public:
ContiguousInternalMemoryAlgorithmDataFacade( ContiguousInternalMemoryAlgorithmDataFacade(
std::shared_ptr<ContiguousBlockAllocator> allocator_) std::shared_ptr<ContiguousBlockAllocator> allocator_)
@ -98,21 +88,8 @@ class ContiguousInternalMemoryAlgorithmDataFacade<algorithm::CH>
void InitializeInternalPointers(storage::DataLayout &data_layout, char *memory_block) void InitializeInternalPointers(storage::DataLayout &data_layout, char *memory_block)
{ {
InitializeGraphPointer(data_layout, memory_block); InitializeGraphPointer(data_layout, memory_block);
InitializeCoreInformationPointer(data_layout, memory_block);
} }
bool IsCoreNode(const NodeID id) const override final
{
if (m_is_core_node.size() > 0)
{
return m_is_core_node.at(id);
}
return false;
}
std::size_t GetCoreSize() const override final { return m_is_core_node.size(); }
// search graph access // search graph access
unsigned GetNumberOfNodes() const override final { return m_query_graph->GetNumberOfNodes(); } unsigned GetNumberOfNodes() const override final { return m_query_graph->GetNumberOfNodes(); }
@ -164,6 +141,51 @@ class ContiguousInternalMemoryAlgorithmDataFacade<algorithm::CH>
} }
}; };
template <>
class ContiguousInternalMemoryAlgorithmDataFacade<algorithm::CoreCH>
: public datafacade::AlgorithmDataFacade<algorithm::CoreCH>
{
private:
util::ShM<bool, true>::vector m_is_core_node;
// allocator that keeps the allocation data
std::shared_ptr<ContiguousBlockAllocator> allocator;
void InitializeCoreInformationPointer(storage::DataLayout &data_layout, char *memory_block)
{
auto core_marker_ptr =
data_layout.GetBlockPtr<unsigned>(memory_block, storage::DataLayout::CH_CORE_MARKER);
util::ShM<bool, true>::vector is_core_node(
core_marker_ptr, data_layout.num_entries[storage::DataLayout::CH_CORE_MARKER]);
m_is_core_node = std::move(is_core_node);
}
public:
ContiguousInternalMemoryAlgorithmDataFacade(
std::shared_ptr<ContiguousBlockAllocator> allocator_)
: allocator(std::move(allocator_))
{
InitializeInternalPointers(allocator->GetLayout(), allocator->GetMemory());
}
void InitializeInternalPointers(storage::DataLayout &data_layout, char *memory_block)
{
InitializeCoreInformationPointer(data_layout, memory_block);
}
bool IsCoreNode(const NodeID id) const override final
{
if (m_is_core_node.size() > 0)
{
return m_is_core_node.at(id);
}
return false;
}
std::size_t GetCoreSize() const override final { return m_is_core_node.size(); }
};
/** /**
* This base class implements the Datafacade interface for accessing * This base class implements the Datafacade interface for accessing
* data that's stored in a single large block of memory (RAM). * data that's stored in a single large block of memory (RAM).
@ -1050,6 +1072,20 @@ class ContiguousInternalMemoryDataFacade<algorithm::CH>
{ {
} }
}; };
template <>
class ContiguousInternalMemoryDataFacade<algorithm::CoreCH> final
: public ContiguousInternalMemoryDataFacade<algorithm::CH>,
public ContiguousInternalMemoryAlgorithmDataFacade<algorithm::CoreCH>
{
public:
ContiguousInternalMemoryDataFacade(std::shared_ptr<ContiguousBlockAllocator> allocator)
: ContiguousInternalMemoryDataFacade<algorithm::CH>(allocator),
ContiguousInternalMemoryAlgorithmDataFacade<algorithm::CoreCH>(allocator)
{
}
};
} }
} }
} }

View File

@ -125,6 +125,8 @@ template <typename AlgorithmT> class Engine final : public EngineInterface
return tile_plugin.HandleRequest(*facade, algorithms, params, result); return tile_plugin.HandleRequest(*facade, algorithms, params, result);
} }
static bool CheckCompability(const EngineConfig &config);
private: private:
std::unique_ptr<DataFacadeProvider<AlgorithmT>> facade_provider; std::unique_ptr<DataFacadeProvider<AlgorithmT>> facade_provider;
mutable SearchEngineData heaps; mutable SearchEngineData heaps;
@ -136,6 +138,54 @@ template <typename AlgorithmT> class Engine final : public EngineInterface
const plugins::MatchPlugin match_plugin; const plugins::MatchPlugin match_plugin;
const plugins::TilePlugin tile_plugin; const plugins::TilePlugin tile_plugin;
}; };
template <> bool Engine<algorithm::CH>::CheckCompability(const EngineConfig &config)
{
if (config.use_shared_memory)
{
storage::SharedMonitor<storage::SharedDataTimestamp> barrier;
using mutex_type = typename decltype(barrier)::mutex_type;
boost::interprocess::scoped_lock<mutex_type> current_region_lock(barrier.get_mutex());
auto mem = storage::makeSharedMemory(barrier.data().region);
auto layout = reinterpret_cast<storage::DataLayout *>(mem->Ptr());
return layout->GetBlockSize(storage::DataLayout::CH_GRAPH_NODE_LIST) > 0 &&
layout->GetBlockSize(storage::DataLayout::CH_GRAPH_EDGE_LIST) > 0;
}
else
{
std::ifstream in(config.storage_config.hsgr_data_path.string().c_str());
in.seekg(std::ios::end);
auto size = in.tellg();
return size > 0;
}
}
template <> bool Engine<algorithm::CoreCH>::CheckCompability(const EngineConfig &config)
{
if (!Engine<algorithm::CH>::CheckCompability(config))
{
return false;
}
if (config.use_shared_memory)
{
storage::SharedMonitor<storage::SharedDataTimestamp> barrier;
using mutex_type = typename decltype(barrier)::mutex_type;
boost::interprocess::scoped_lock<mutex_type> current_region_lock(barrier.get_mutex());
auto mem = storage::makeSharedMemory(barrier.data().region);
auto layout = reinterpret_cast<storage::DataLayout *>(mem->Ptr());
return layout->GetBlockSize(storage::DataLayout::CH_CORE_MARKER) > 0;
}
else
{
std::ifstream in(config.storage_config.core_data_path.string().c_str());
in.seekg(std::ios::end);
auto size = in.tellg();
return size > 0;
}
}
} }
} }

View File

@ -19,19 +19,20 @@ namespace engine
class RoutingAlgorithmsInterface class RoutingAlgorithmsInterface
{ {
public: public:
virtual InternalRouteResult AlternativePathSearch(const PhantomNodes &phantom_node_pair) const = 0; virtual InternalRouteResult
AlternativePathSearch(const PhantomNodes &phantom_node_pair) const = 0;
virtual InternalRouteResult virtual InternalRouteResult
ShortestPathSearch(const std::vector<PhantomNodes> &phantom_node_pair, ShortestPathSearch(const std::vector<PhantomNodes> &phantom_node_pair,
const boost::optional<bool> continue_straight_at_waypoint) const = 0; const boost::optional<bool> continue_straight_at_waypoint) const = 0;
virtual InternalRouteResult virtual InternalRouteResult
DirectShortestPathSearch(const std::vector<PhantomNodes> &phantom_node_pair) const = 0; DirectShortestPathSearch(const PhantomNodes &phantom_node_pair) const = 0;
virtual std::vector<EdgeWeight> virtual std::vector<EdgeWeight>
ManyToManySearch(const std::vector<PhantomNode> &phantom_nodes, ManyToManySearch(const std::vector<PhantomNode> &phantom_nodes,
const std::vector<std::size_t> &source_indices, const std::vector<std::size_t> &source_indices,
const std::vector<std::size_t> &target_indices) const = 0; const std::vector<std::size_t> &target_indices) const = 0;
virtual routing_algorithms::SubMatchingList virtual routing_algorithms::SubMatchingList
MapMatching(const routing_algorithms::CandidateLists &candidates_list, MapMatching(const routing_algorithms::CandidateLists &candidates_list,
@ -41,7 +42,7 @@ class RoutingAlgorithmsInterface
virtual std::vector<routing_algorithms::TurnData> virtual std::vector<routing_algorithms::TurnData>
GetTileTurns(const std::vector<datafacade::BaseDataFacade::RTreeLeaf> &edges, GetTileTurns(const std::vector<datafacade::BaseDataFacade::RTreeLeaf> &edges,
const std::vector<std::size_t> &sorted_edge_indexes) const = 0; const std::vector<std::size_t> &sorted_edge_indexes) const = 0;
virtual bool HasAlternativePathSearch() const = 0; virtual bool HasAlternativePathSearch() const = 0;
virtual bool HasShortestPathSearch() const = 0; virtual bool HasShortestPathSearch() const = 0;
@ -54,8 +55,9 @@ class RoutingAlgorithmsInterface
namespace detail namespace detail
{ {
struct NotImplementedException : public std::runtime_error {}; struct NotImplementedException : public std::runtime_error
{
};
} }
// Short-lived object passed to each plugin in request to wrap routing algorithms // Short-lived object passed to each plugin in request to wrap routing algorithms
@ -74,24 +76,24 @@ template <typename AlgorithmT> class RoutingAlgorithms final : public RoutingAlg
return routing_algorithms::alternativePathSearch(heaps, facade, phantom_node_pair); return routing_algorithms::alternativePathSearch(heaps, facade, phantom_node_pair);
} }
InternalRouteResult InternalRouteResult ShortestPathSearch(
ShortestPathSearch(const std::vector<PhantomNodes> &phantom_node_pair, const std::vector<PhantomNodes> &phantom_node_pair,
const boost::optional<bool> continue_straight_at_waypoint) const final override const boost::optional<bool> continue_straight_at_waypoint) const final override
{ {
return routing_algorithms::shortestPathSearch( return routing_algorithms::shortestPathSearch(
heaps, facade, phantom_node_pair, continue_straight_at_waypoint); heaps, facade, phantom_node_pair, continue_straight_at_waypoint);
} }
InternalRouteResult DirectShortestPathSearch( InternalRouteResult
const std::vector<PhantomNodes> &phantom_node_pair) const final override DirectShortestPathSearch(const PhantomNodes &phantom_nodes) const final override
{ {
return routing_algorithms::directShortestPathSearch(heaps, facade, phantom_node_pair); return routing_algorithms::directShortestPathSearch(heaps, facade, phantom_nodes);
} }
std::vector<EdgeWeight> std::vector<EdgeWeight>
ManyToManySearch(const std::vector<PhantomNode> &phantom_nodes, ManyToManySearch(const std::vector<PhantomNode> &phantom_nodes,
const std::vector<std::size_t> &source_indices, const std::vector<std::size_t> &source_indices,
const std::vector<std::size_t> &target_indices) const final override const std::vector<std::size_t> &target_indices) const final override
{ {
return routing_algorithms::manyToManySearch( return routing_algorithms::manyToManySearch(
heaps, facade, phantom_nodes, source_indices, target_indices); heaps, facade, phantom_nodes, source_indices, target_indices);
@ -113,7 +115,7 @@ template <typename AlgorithmT> class RoutingAlgorithms final : public RoutingAlg
std::vector<routing_algorithms::TurnData> std::vector<routing_algorithms::TurnData>
GetTileTurns(const std::vector<datafacade::BaseDataFacade::RTreeLeaf> &edges, GetTileTurns(const std::vector<datafacade::BaseDataFacade::RTreeLeaf> &edges,
const std::vector<std::size_t> &sorted_edge_indexes) const final override const std::vector<std::size_t> &sorted_edge_indexes) const final override
{ {
return routing_algorithms::getTileTurns(facade, edges, sorted_edge_indexes); return routing_algorithms::getTileTurns(facade, edges, sorted_edge_indexes);
} }

View File

@ -34,7 +34,12 @@ directShortestPathSearch(SearchEngineData &,
InternalRouteResult directShortestPathSearch( InternalRouteResult directShortestPathSearch(
SearchEngineData &engine_working_data, SearchEngineData &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade, const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
const std::vector<PhantomNodes> &phantom_nodes_vector); const PhantomNodes &phantom_nodes);
InternalRouteResult directShortestPathSearch(
SearchEngineData &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CoreCH> &facade,
const PhantomNodes &phantom_nodes);
} // namespace routing_algorithms } // namespace routing_algorithms
} // namespace engine } // namespace engine

View File

@ -39,6 +39,14 @@ mapMatching(SearchEngineData &engine_working_data,
const std::vector<util::Coordinate> &trace_coordinates, const std::vector<util::Coordinate> &trace_coordinates,
const std::vector<unsigned> &trace_timestamps, const std::vector<unsigned> &trace_timestamps,
const std::vector<boost::optional<double>> &trace_gps_precision); const std::vector<boost::optional<double>> &trace_gps_precision);
SubMatchingList
mapMatching(SearchEngineData &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CoreCH> &facade,
const CandidateLists &candidates_list,
const std::vector<util::Coordinate> &trace_coordinates,
const std::vector<unsigned> &trace_timestamps,
const std::vector<boost::optional<double>> &trace_gps_precision);
} }
} }
} }

View File

@ -452,6 +452,28 @@ void search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH>
const bool force_loop_reverse, const bool force_loop_reverse,
const int duration_upper_bound = INVALID_EDGE_WEIGHT); const int duration_upper_bound = INVALID_EDGE_WEIGHT);
// Alias to be compatible with the overload for CoreCH that needs 4 heaps
inline void search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
SearchEngineData::QueryHeap &forward_heap,
SearchEngineData::QueryHeap &reverse_heap,
SearchEngineData::QueryHeap &,
SearchEngineData::QueryHeap &,
std::int32_t &weight,
std::vector<NodeID> &packed_leg,
const bool force_loop_forward,
const bool force_loop_reverse,
const int duration_upper_bound = INVALID_EDGE_WEIGHT)
{
search(facade,
forward_heap,
reverse_heap,
weight,
packed_leg,
force_loop_forward,
force_loop_reverse,
duration_upper_bound);
}
// assumes that heaps are already setup correctly. // assumes that heaps are already setup correctly.
// A forced loop might be necessary, if source and target are on the same segment. // 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 // If this is the case and the offsets of the respective direction are larger for the source
@ -461,16 +483,16 @@ void search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH>
// && source_phantom.GetForwardWeightPlusOffset() > target_phantom.GetForwardWeightPlusOffset()) // && source_phantom.GetForwardWeightPlusOffset() > target_phantom.GetForwardWeightPlusOffset())
// requires // requires
// a force loop, if the heaps have been initialized with positive offsets. // a force loop, if the heaps have been initialized with positive offsets.
void searchWithCore(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade, void search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CoreCH> &facade,
SearchEngineData::QueryHeap &forward_heap, SearchEngineData::QueryHeap &forward_heap,
SearchEngineData::QueryHeap &reverse_heap, SearchEngineData::QueryHeap &reverse_heap,
SearchEngineData::QueryHeap &forward_core_heap, SearchEngineData::QueryHeap &forward_core_heap,
SearchEngineData::QueryHeap &reverse_core_heap, SearchEngineData::QueryHeap &reverse_core_heap,
int &weight, int &weight,
std::vector<NodeID> &packed_leg, std::vector<NodeID> &packed_leg,
const bool force_loop_forward, const bool force_loop_forward,
const bool force_loop_reverse, const bool force_loop_reverse,
int duration_upper_bound = INVALID_EDGE_WEIGHT); int duration_upper_bound = INVALID_EDGE_WEIGHT);
bool needsLoopForward(const PhantomNode &source_phantom, const PhantomNode &target_phantom); bool needsLoopForward(const PhantomNode &source_phantom, const PhantomNode &target_phantom);
@ -484,15 +506,15 @@ double getPathDistance(const datafacade::ContiguousInternalMemoryDataFacade<algo
// Requires the heaps for be empty // Requires the heaps for be empty
// If heaps should be adjusted to be initialized outside of this function, // If heaps should be adjusted to be initialized outside of this function,
// the addition of force_loop parameters might be required // the addition of force_loop parameters might be required
double getNetworkDistanceWithCore( double
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade, getNetworkDistance(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CoreCH> &facade,
SearchEngineData::QueryHeap &forward_heap, SearchEngineData::QueryHeap &forward_heap,
SearchEngineData::QueryHeap &reverse_heap, SearchEngineData::QueryHeap &reverse_heap,
SearchEngineData::QueryHeap &forward_core_heap, SearchEngineData::QueryHeap &forward_core_heap,
SearchEngineData::QueryHeap &reverse_core_heap, SearchEngineData::QueryHeap &reverse_core_heap,
const PhantomNode &source_phantom, const PhantomNode &source_phantom,
const PhantomNode &target_phantom, const PhantomNode &target_phantom,
int duration_upper_bound = INVALID_EDGE_WEIGHT); int duration_upper_bound = INVALID_EDGE_WEIGHT);
// Requires the heaps for be empty // Requires the heaps for be empty
// If heaps should be adjusted to be initialized outside of this function, // If heaps should be adjusted to be initialized outside of this function,
@ -505,6 +527,21 @@ getNetworkDistance(const datafacade::ContiguousInternalMemoryDataFacade<algorith
const PhantomNode &target_phantom, const PhantomNode &target_phantom,
int duration_upper_bound = INVALID_EDGE_WEIGHT); int duration_upper_bound = INVALID_EDGE_WEIGHT);
// Alias to be compatible with the overload for CoreCH that needs 4 heaps
inline double
getNetworkDistance(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
SearchEngineData::QueryHeap &forward_heap,
SearchEngineData::QueryHeap &reverse_heap,
SearchEngineData::QueryHeap &,
SearchEngineData::QueryHeap &,
const PhantomNode &source_phantom,
const PhantomNode &target_phantom,
int duration_upper_bound = INVALID_EDGE_WEIGHT)
{
return getNetworkDistance(
facade, forward_heap, reverse_heap, source_phantom, target_phantom, duration_upper_bound);
}
} // namespace routing_algorithms } // namespace routing_algorithms
} // namespace engine } // namespace engine
} // namespace osrm } // namespace osrm

View File

@ -30,6 +30,12 @@ shortestPathSearch(SearchEngineData &engine_working_data,
const std::vector<PhantomNodes> &phantom_nodes_vector, const std::vector<PhantomNodes> &phantom_nodes_vector,
const boost::optional<bool> continue_straight_at_waypoint); const boost::optional<bool> continue_straight_at_waypoint);
InternalRouteResult
shortestPathSearch(SearchEngineData &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CoreCH> &facade,
const std::vector<PhantomNodes> &phantom_nodes_vector,
const boost::optional<bool> continue_straight_at_waypoint);
} // namespace routing_algorithms } // namespace routing_algorithms
} // namespace engine } // namespace engine
} // namespace osrm } // namespace osrm

View File

@ -115,7 +115,9 @@ Status MatchPlugin::HandleRequest(const datafacade::ContiguousInternalMemoryData
{ {
if (!algorithms.HasMapMatching()) if (!algorithms.HasMapMatching())
{ {
return Error("NotImplemented", "Map matching is not implemented for the chosen search algorithm.", json_result); return Error("NotImplemented",
"Map matching is not implemented for the chosen search algorithm.",
json_result);
} }
BOOST_ASSERT(parameters.IsValid()); BOOST_ASSERT(parameters.IsValid());

View File

@ -35,7 +35,9 @@ Status TablePlugin::HandleRequest(const datafacade::ContiguousInternalMemoryData
{ {
if (!algorithms.HasManyToManySearch()) if (!algorithms.HasManyToManySearch())
{ {
return Error("NotImplemented", "Many to many search is not implemented for the chosen search algorithm.", result); return Error("NotImplemented",
"Many to many search is not implemented for the chosen search algorithm.",
result);
} }
BOOST_ASSERT(params.IsValid()); BOOST_ASSERT(params.IsValid());

View File

@ -149,11 +149,15 @@ Status TripPlugin::HandleRequest(const datafacade::ContiguousInternalMemoryDataF
{ {
if (!algorithms.HasShortestPathSearch()) if (!algorithms.HasShortestPathSearch())
{ {
return Error("NotImplemented", "Shortest path search is not implemented for the chosen search algorithm.", json_result); return Error("NotImplemented",
"Shortest path search is not implemented for the chosen search algorithm.",
json_result);
} }
if (!algorithms.HasManyToManySearch()) if (!algorithms.HasManyToManySearch())
{ {
return Error("NotImplemented", "Many to many search is not implemented for the chosen search algorithm.", json_result); return Error("NotImplemented",
"Many to many search is not implemented for the chosen search algorithm.",
json_result);
} }
BOOST_ASSERT(parameters.IsValid()); BOOST_ASSERT(parameters.IsValid());

View File

@ -36,12 +36,18 @@ ViaRoutePlugin::HandleRequest(const datafacade::ContiguousInternalMemoryDataFaca
if (!algorithms.HasShortestPathSearch() && route_parameters.coordinates.size() > 2) if (!algorithms.HasShortestPathSearch() && route_parameters.coordinates.size() > 2)
{ {
return Error("NotImplemented", "Shortest path search is not implemented for the chosen search algorithm. Only two coordinates supported.", json_result); return Error("NotImplemented",
"Shortest path search is not implemented for the chosen search algorithm. "
"Only two coordinates supported.",
json_result);
} }
if (!algorithms.HasDirectShortestPathSearch() && !algorithms.HasShortestPathSearch()) if (!algorithms.HasDirectShortestPathSearch() && !algorithms.HasShortestPathSearch())
{ {
return Error("NotImplemented", "Direct shortest path search is not implemented for the chosen search algorithm.", json_result); return Error(
"NotImplemented",
"Direct shortest path search is not implemented for the chosen search algorithm.",
json_result);
} }
if (max_locations_viaroute > 0 && if (max_locations_viaroute > 0 &&
@ -95,18 +101,20 @@ ViaRoutePlugin::HandleRequest(const datafacade::ContiguousInternalMemoryDataFaca
}; };
util::for_each_pair(snapped_phantoms, build_phantom_pairs); util::for_each_pair(snapped_phantoms, build_phantom_pairs);
if (1 == raw_route.segment_end_coordinates.size() && algorithms.HasAlternativePathSearch() && route_parameters.alternatives) if (1 == raw_route.segment_end_coordinates.size() && algorithms.HasAlternativePathSearch() &&
route_parameters.alternatives)
{ {
raw_route = algorithms.AlternativePathSearch(raw_route.segment_end_coordinates.front()); raw_route = algorithms.AlternativePathSearch(raw_route.segment_end_coordinates.front());
} }
else if (1 == raw_route.segment_end_coordinates.size() && algorithms.HasDirectShortestPathSearch()) else if (1 == raw_route.segment_end_coordinates.size() &&
algorithms.HasDirectShortestPathSearch())
{ {
raw_route = algorithms.DirectShortestPathSearch(raw_route.segment_end_coordinates); raw_route = algorithms.DirectShortestPathSearch(raw_route.segment_end_coordinates.front());
} }
else else
{ {
raw_route = algorithms.ShortestPathSearch(raw_route.segment_end_coordinates, raw_route = algorithms.ShortestPathSearch(raw_route.segment_end_coordinates,
route_parameters.continue_straight); route_parameters.continue_straight);
} }
// we can only know this after the fact, different SCC ids still // we can only know this after the fact, different SCC ids still

View File

@ -9,32 +9,14 @@ namespace engine
namespace routing_algorithms namespace routing_algorithms
{ {
/// This is a striped down version of the general shortest path algorithm. namespace
/// The general algorithm always computes two queries for each leg. This is only
/// necessary in case of vias, where the directions of the start node is constrainted
/// by the previous route.
/// This variation is only an optimazation for graphs with slow queries, for example
/// not fully contracted graphs.
InternalRouteResult directShortestPathSearch(
SearchEngineData &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
const std::vector<PhantomNodes> &phantom_nodes_vector)
{ {
InternalRouteResult raw_route_data; void insertInHeaps(SearchEngineData::QueryHeap &forward_heap,
// Get weight to next pair of target nodes. SearchEngineData::QueryHeap &reverse_heap,
BOOST_ASSERT_MSG(1 == phantom_nodes_vector.size(), const PhantomNodes &nodes)
"Direct Shortest Path Query only accepts a single source and target pair. " {
"Multiple ones have been specified."); const auto &source_phantom = nodes.source_phantom;
const auto &phantom_node_pair = phantom_nodes_vector.front(); const auto &target_phantom = nodes.target_phantom;
const auto &source_phantom = phantom_node_pair.source_phantom;
const auto &target_phantom = phantom_node_pair.target_phantom;
engine_working_data.InitializeOrClearFirstThreadLocalStorage(facade.GetNumberOfNodes());
auto &forward_heap = *(engine_working_data.forward_heap_1);
auto &reverse_heap = *(engine_working_data.reverse_heap_1);
forward_heap.Clear();
reverse_heap.Clear();
BOOST_ASSERT(source_phantom.IsValid()); BOOST_ASSERT(source_phantom.IsValid());
BOOST_ASSERT(target_phantom.IsValid()); BOOST_ASSERT(target_phantom.IsValid());
@ -64,42 +46,16 @@ InternalRouteResult directShortestPathSearch(
target_phantom.GetReverseWeightPlusOffset(), target_phantom.GetReverseWeightPlusOffset(),
target_phantom.reverse_segment_id.id); target_phantom.reverse_segment_id.id);
} }
}
int weight = INVALID_EDGE_WEIGHT; template <typename AlgorithmT>
std::vector<NodeID> packed_leg; InternalRouteResult
extractRoute(const datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT> &facade,
const bool constexpr DO_NOT_FORCE_LOOPS = const EdgeWeight weight,
false; // prevents forcing of loops, since offsets are set correctly const std::vector<NodeID> &packed_leg,
const PhantomNodes &nodes)
if (facade.GetCoreSize() > 0) {
{ InternalRouteResult raw_route_data;
engine_working_data.InitializeOrClearSecondThreadLocalStorage(facade.GetNumberOfNodes());
auto &forward_core_heap = *(engine_working_data.forward_heap_2);
auto &reverse_core_heap = *(engine_working_data.reverse_heap_2);
forward_core_heap.Clear();
reverse_core_heap.Clear();
searchWithCore(facade,
forward_heap,
reverse_heap,
forward_core_heap,
reverse_core_heap,
weight,
packed_leg,
DO_NOT_FORCE_LOOPS,
DO_NOT_FORCE_LOOPS);
}
else
{
search(facade,
forward_heap,
reverse_heap,
weight,
packed_leg,
DO_NOT_FORCE_LOOPS,
DO_NOT_FORCE_LOOPS);
}
// No path found for both target nodes? // No path found for both target nodes?
if (INVALID_EDGE_WEIGHT == weight) if (INVALID_EDGE_WEIGHT == weight)
{ {
@ -113,18 +69,79 @@ InternalRouteResult directShortestPathSearch(
raw_route_data.shortest_path_length = weight; raw_route_data.shortest_path_length = weight;
raw_route_data.unpacked_path_segments.resize(1); raw_route_data.unpacked_path_segments.resize(1);
raw_route_data.source_traversed_in_reverse.push_back( raw_route_data.source_traversed_in_reverse.push_back(
(packed_leg.front() != phantom_node_pair.source_phantom.forward_segment_id.id)); (packed_leg.front() != nodes.source_phantom.forward_segment_id.id));
raw_route_data.target_traversed_in_reverse.push_back( raw_route_data.target_traversed_in_reverse.push_back(
(packed_leg.back() != phantom_node_pair.target_phantom.forward_segment_id.id)); (packed_leg.back() != nodes.target_phantom.forward_segment_id.id));
unpackPath(facade, unpackPath(facade,
packed_leg.begin(), packed_leg.begin(),
packed_leg.end(), packed_leg.end(),
phantom_node_pair, nodes,
raw_route_data.unpacked_path_segments.front()); raw_route_data.unpacked_path_segments.front());
return raw_route_data; return raw_route_data;
} }
// prevents forcing of loops, since offsets are set correctly
static const bool constexpr DO_NOT_FORCE_LOOPS = false;
}
/// This is a striped down version of the general shortest path algorithm.
/// The general algorithm always computes two queries for each leg. This is only
/// necessary in case of vias, where the directions of the start node is constrainted
/// by the previous route.
/// This variation is only an optimazation for graphs with slow queries, for example
/// not fully contracted graphs.
template <typename AlgorithmT>
InternalRouteResult directShortestPathSearchImpl(
SearchEngineData &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT> &facade,
const PhantomNodes &phantom_nodes)
{
engine_working_data.InitializeOrClearFirstThreadLocalStorage(facade.GetNumberOfNodes());
engine_working_data.InitializeOrClearSecondThreadLocalStorage(facade.GetNumberOfNodes());
auto &forward_heap = *(engine_working_data.forward_heap_1);
auto &reverse_heap = *(engine_working_data.reverse_heap_1);
auto &forward_core_heap = *(engine_working_data.forward_heap_2);
auto &reverse_core_heap = *(engine_working_data.reverse_heap_2);
forward_heap.Clear();
reverse_heap.Clear();
forward_core_heap.Clear();
reverse_core_heap.Clear();
int weight = INVALID_EDGE_WEIGHT;
std::vector<NodeID> packed_leg;
insertInHeaps(forward_heap, reverse_heap, phantom_nodes);
search(facade,
forward_heap,
reverse_heap,
forward_core_heap,
reverse_core_heap,
weight,
packed_leg,
DO_NOT_FORCE_LOOPS,
DO_NOT_FORCE_LOOPS);
return extractRoute(facade, weight, packed_leg, phantom_nodes);
}
InternalRouteResult directShortestPathSearch(
SearchEngineData &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CoreCH> &facade,
const PhantomNodes &phantom_nodes)
{
return directShortestPathSearchImpl(engine_working_data, facade, phantom_nodes);
}
InternalRouteResult directShortestPathSearch(
SearchEngineData &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
const PhantomNodes &phantom_nodes)
{
return directShortestPathSearchImpl(engine_working_data, facade, phantom_nodes);
}
} // namespace routing_algorithms } // namespace routing_algorithms
} // namespace engine } // namespace engine
} // namespace osrm } // namespace osrm

View File

@ -47,13 +47,14 @@ unsigned getMedianSampleTime(const std::vector<unsigned> &timestamps)
} }
} }
template <typename AlgorithmT>
SubMatchingList SubMatchingList
mapMatching(SearchEngineData &engine_working_data, mapMatchingImpl(SearchEngineData &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade, const datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT> &facade,
const CandidateLists &candidates_list, const CandidateLists &candidates_list,
const std::vector<util::Coordinate> &trace_coordinates, const std::vector<util::Coordinate> &trace_coordinates,
const std::vector<unsigned> &trace_timestamps, const std::vector<unsigned> &trace_timestamps,
const std::vector<boost::optional<double>> &trace_gps_precision) const std::vector<boost::optional<double>> &trace_gps_precision)
{ {
map_matching::MatchingConfidence confidence; map_matching::MatchingConfidence confidence;
map_matching::EmissionLogProbability default_emission_log_probability(DEFAULT_GPS_PRECISION); map_matching::EmissionLogProbability default_emission_log_probability(DEFAULT_GPS_PRECISION);
@ -208,33 +209,15 @@ mapMatching(SearchEngineData &engine_working_data,
continue; continue;
} }
forward_heap.Clear(); double network_distance =
reverse_heap.Clear(); getNetworkDistance(facade,
forward_heap,
double network_distance; reverse_heap,
if (facade.GetCoreSize() > 0) forward_core_heap,
{ reverse_core_heap,
forward_core_heap.Clear(); prev_unbroken_timestamps_list[s].phantom_node,
reverse_core_heap.Clear(); current_timestamps_list[s_prime].phantom_node,
network_distance = getNetworkDistanceWithCore( duration_upper_bound);
facade,
forward_heap,
reverse_heap,
forward_core_heap,
reverse_core_heap,
prev_unbroken_timestamps_list[s].phantom_node,
current_timestamps_list[s_prime].phantom_node,
duration_upper_bound);
}
else
{
network_distance =
getNetworkDistance(facade,
forward_heap,
reverse_heap,
prev_unbroken_timestamps_list[s].phantom_node,
current_timestamps_list[s_prime].phantom_node);
}
// get distance diff between loc1/2 and locs/s_prime // get distance diff between loc1/2 and locs/s_prime
const auto d_t = std::abs(network_distance - haversine_distance); const auto d_t = std::abs(network_distance - haversine_distance);
@ -427,6 +410,39 @@ mapMatching(SearchEngineData &engine_working_data,
return sub_matchings; return sub_matchings;
} }
SubMatchingList
mapMatching(SearchEngineData &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
const CandidateLists &candidates_list,
const std::vector<util::Coordinate> &trace_coordinates,
const std::vector<unsigned> &trace_timestamps,
const std::vector<boost::optional<double>> &trace_gps_precision)
{
return mapMatchingImpl(engine_working_data,
facade,
candidates_list,
trace_coordinates,
trace_timestamps,
trace_gps_precision);
}
SubMatchingList
mapMatching(SearchEngineData &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CoreCH> &facade,
const CandidateLists &candidates_list,
const std::vector<util::Coordinate> &trace_coordinates,
const std::vector<unsigned> &trace_timestamps,
const std::vector<boost::optional<double>> &trace_gps_precision)
{
return mapMatchingImpl(engine_working_data,
facade,
candidates_list,
trace_coordinates,
trace_timestamps,
trace_gps_precision);
}
} // namespace routing_algorithms } // namespace routing_algorithms
} // namespace engine } // namespace engine
} // namespace osrm } // namespace osrm

View File

@ -270,16 +270,16 @@ void search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH>
// && source_phantom.GetForwardWeightPlusOffset() > target_phantom.GetForwardWeightPlusOffset()) // && source_phantom.GetForwardWeightPlusOffset() > target_phantom.GetForwardWeightPlusOffset())
// requires // requires
// a force loop, if the heaps have been initialized with positive offsets. // a force loop, if the heaps have been initialized with positive offsets.
void searchWithCore(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade, void search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CoreCH> &facade,
SearchEngineData::QueryHeap &forward_heap, SearchEngineData::QueryHeap &forward_heap,
SearchEngineData::QueryHeap &reverse_heap, SearchEngineData::QueryHeap &reverse_heap,
SearchEngineData::QueryHeap &forward_core_heap, SearchEngineData::QueryHeap &forward_core_heap,
SearchEngineData::QueryHeap &reverse_core_heap, SearchEngineData::QueryHeap &reverse_core_heap,
EdgeWeight &weight, EdgeWeight &weight,
std::vector<NodeID> &packed_leg, std::vector<NodeID> &packed_leg,
const bool force_loop_forward, const bool force_loop_forward,
const bool force_loop_reverse, const bool force_loop_reverse,
EdgeWeight weight_upper_bound) EdgeWeight weight_upper_bound)
{ {
NodeID middle = SPECIAL_NODEID; NodeID middle = SPECIAL_NODEID;
weight = weight_upper_bound; weight = weight_upper_bound;
@ -530,18 +530,20 @@ double getPathDistance(const datafacade::ContiguousInternalMemoryDataFacade<algo
// Requires the heaps for be empty // Requires the heaps for be empty
// If heaps should be adjusted to be initialized outside of this function, // If heaps should be adjusted to be initialized outside of this function,
// the addition of force_loop parameters might be required // the addition of force_loop parameters might be required
double getNetworkDistanceWithCore( double
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade, getNetworkDistance(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CoreCH> &facade,
SearchEngineData::QueryHeap &forward_heap, SearchEngineData::QueryHeap &forward_heap,
SearchEngineData::QueryHeap &reverse_heap, SearchEngineData::QueryHeap &reverse_heap,
SearchEngineData::QueryHeap &forward_core_heap, SearchEngineData::QueryHeap &forward_core_heap,
SearchEngineData::QueryHeap &reverse_core_heap, SearchEngineData::QueryHeap &reverse_core_heap,
const PhantomNode &source_phantom, const PhantomNode &source_phantom,
const PhantomNode &target_phantom, const PhantomNode &target_phantom,
EdgeWeight weight_upper_bound) EdgeWeight weight_upper_bound)
{ {
BOOST_ASSERT(forward_heap.Empty()); forward_heap.Clear();
BOOST_ASSERT(reverse_heap.Empty()); reverse_heap.Clear();
forward_core_heap.Clear();
reverse_core_heap.Clear();
if (source_phantom.forward_segment_id.enabled) if (source_phantom.forward_segment_id.enabled)
{ {
@ -574,16 +576,16 @@ double getNetworkDistanceWithCore(
EdgeWeight weight = INVALID_EDGE_WEIGHT; EdgeWeight weight = INVALID_EDGE_WEIGHT;
std::vector<NodeID> packed_path; std::vector<NodeID> packed_path;
searchWithCore(facade, search(facade,
forward_heap, forward_heap,
reverse_heap, reverse_heap,
forward_core_heap, forward_core_heap,
reverse_core_heap, reverse_core_heap,
weight, weight,
packed_path, packed_path,
DO_NOT_FORCE_LOOPS, DO_NOT_FORCE_LOOPS,
DO_NOT_FORCE_LOOPS, DO_NOT_FORCE_LOOPS,
weight_upper_bound); weight_upper_bound);
double distance = std::numeric_limits<double>::max(); double distance = std::numeric_limits<double>::max();
if (weight != INVALID_EDGE_WEIGHT) if (weight != INVALID_EDGE_WEIGHT)
@ -604,8 +606,8 @@ getNetworkDistance(const datafacade::ContiguousInternalMemoryDataFacade<algorith
const PhantomNode &target_phantom, const PhantomNode &target_phantom,
EdgeWeight weight_upper_bound) EdgeWeight weight_upper_bound)
{ {
BOOST_ASSERT(forward_heap.Empty()); forward_heap.Clear();
BOOST_ASSERT(reverse_heap.Empty()); reverse_heap.Clear();
if (source_phantom.forward_segment_id.enabled) if (source_phantom.forward_segment_id.enabled)
{ {

View File

@ -12,12 +12,16 @@ namespace engine
namespace routing_algorithms namespace routing_algorithms
{ {
namespace
{
const static constexpr bool DO_NOT_FORCE_LOOP = false; const static constexpr bool DO_NOT_FORCE_LOOP = false;
using QueryHeap = SearchEngineData::QueryHeap; using QueryHeap = SearchEngineData::QueryHeap;
// allows a uturn at the target_phantom // allows a uturn at the target_phantom
// searches source forward/reverse -> target forward/reverse // searches source forward/reverse -> target forward/reverse
void searchWithUTurn(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade, template <typename AlgorithmT>
void searchWithUTurn(const datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT> &facade,
QueryHeap &forward_heap, QueryHeap &forward_heap,
QueryHeap &reverse_heap, QueryHeap &reverse_heap,
QueryHeap &forward_core_heap, QueryHeap &forward_core_heap,
@ -70,32 +74,21 @@ void searchWithUTurn(const datafacade::ContiguousInternalMemoryDataFacade<algori
auto needs_loop_forwad = is_oneway_source && needsLoopForward(source_phantom, target_phantom); auto needs_loop_forwad = is_oneway_source && needsLoopForward(source_phantom, target_phantom);
auto needs_loop_backwards = auto needs_loop_backwards =
is_oneway_target && needsLoopBackwards(source_phantom, target_phantom); is_oneway_target && needsLoopBackwards(source_phantom, target_phantom);
if (facade.GetCoreSize() > 0)
{ forward_core_heap.Clear();
forward_core_heap.Clear(); reverse_core_heap.Clear();
reverse_core_heap.Clear(); BOOST_ASSERT(forward_core_heap.Size() == 0);
BOOST_ASSERT(forward_core_heap.Size() == 0); BOOST_ASSERT(reverse_core_heap.Size() == 0);
BOOST_ASSERT(reverse_core_heap.Size() == 0); routing_algorithms::search(facade,
searchWithCore(facade, forward_heap,
forward_heap, reverse_heap,
reverse_heap, forward_core_heap,
forward_core_heap, reverse_core_heap,
reverse_core_heap, new_total_weight,
new_total_weight, leg_packed_path,
leg_packed_path, needs_loop_forwad,
needs_loop_forwad, needs_loop_backwards);
needs_loop_backwards);
}
else
{
search(facade,
forward_heap,
reverse_heap,
new_total_weight,
leg_packed_path,
needs_loop_forwad,
needs_loop_backwards);
}
// if no route is found between two parts of the via-route, the entire route becomes // if no route is found between two parts of the via-route, the entire route becomes
// invalid. Adding to invalid edge weight sadly doesn't return an invalid edge weight. Here // invalid. Adding to invalid edge weight sadly doesn't return an invalid edge weight. Here
// we prevent the possible overflow, faking the addition of infinity + x == infinity // we prevent the possible overflow, faking the addition of infinity + x == infinity
@ -106,7 +99,8 @@ void searchWithUTurn(const datafacade::ContiguousInternalMemoryDataFacade<algori
// searches shortest path between: // searches shortest path between:
// source forward/reverse -> target forward // source forward/reverse -> target forward
// source forward/reverse -> target reverse // source forward/reverse -> target reverse
void Search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade, template <typename AlgorithmT>
void search(const datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT> &facade,
QueryHeap &forward_heap, QueryHeap &forward_heap,
QueryHeap &reverse_heap, QueryHeap &reverse_heap,
QueryHeap &forward_core_heap, QueryHeap &forward_core_heap,
@ -149,32 +143,19 @@ void Search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH>
BOOST_ASSERT(forward_heap.Size() > 0); BOOST_ASSERT(forward_heap.Size() > 0);
BOOST_ASSERT(reverse_heap.Size() > 0); BOOST_ASSERT(reverse_heap.Size() > 0);
if (facade.GetCoreSize() > 0) forward_core_heap.Clear();
{ reverse_core_heap.Clear();
forward_core_heap.Clear(); BOOST_ASSERT(forward_core_heap.Size() == 0);
reverse_core_heap.Clear(); BOOST_ASSERT(reverse_core_heap.Size() == 0);
BOOST_ASSERT(forward_core_heap.Size() == 0); routing_algorithms::search(facade,
BOOST_ASSERT(reverse_core_heap.Size() == 0); forward_heap,
searchWithCore(facade, reverse_heap,
forward_heap, forward_core_heap,
reverse_heap, reverse_core_heap,
forward_core_heap, new_total_weight_to_forward,
reverse_core_heap, leg_packed_path_forward,
new_total_weight_to_forward, needsLoopForward(source_phantom, target_phantom),
leg_packed_path_forward, DO_NOT_FORCE_LOOP);
needsLoopForward(source_phantom, target_phantom),
DO_NOT_FORCE_LOOP);
}
else
{
search(facade,
forward_heap,
reverse_heap,
new_total_weight_to_forward,
leg_packed_path_forward,
needsLoopForward(source_phantom, target_phantom),
DO_NOT_FORCE_LOOP);
}
} }
if (search_to_reverse_node) if (search_to_reverse_node)
@ -200,32 +181,19 @@ void Search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH>
} }
BOOST_ASSERT(forward_heap.Size() > 0); BOOST_ASSERT(forward_heap.Size() > 0);
BOOST_ASSERT(reverse_heap.Size() > 0); BOOST_ASSERT(reverse_heap.Size() > 0);
if (facade.GetCoreSize() > 0) forward_core_heap.Clear();
{ reverse_core_heap.Clear();
forward_core_heap.Clear(); BOOST_ASSERT(forward_core_heap.Size() == 0);
reverse_core_heap.Clear(); BOOST_ASSERT(reverse_core_heap.Size() == 0);
BOOST_ASSERT(forward_core_heap.Size() == 0); routing_algorithms::search(facade,
BOOST_ASSERT(reverse_core_heap.Size() == 0); forward_heap,
searchWithCore(facade, reverse_heap,
forward_heap, forward_core_heap,
reverse_heap, reverse_core_heap,
forward_core_heap, new_total_weight_to_reverse,
reverse_core_heap, leg_packed_path_reverse,
new_total_weight_to_reverse, DO_NOT_FORCE_LOOP,
leg_packed_path_reverse, needsLoopBackwards(source_phantom, target_phantom));
DO_NOT_FORCE_LOOP,
needsLoopBackwards(source_phantom, target_phantom));
}
else
{
search(facade,
forward_heap,
reverse_heap,
new_total_weight_to_reverse,
leg_packed_path_reverse,
DO_NOT_FORCE_LOOP,
needsLoopBackwards(source_phantom, target_phantom));
}
} }
} }
@ -259,11 +227,12 @@ void unpackLegs(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::
} }
} }
template <typename AlgorithmT>
InternalRouteResult InternalRouteResult
shortestPathSearch(SearchEngineData &engine_working_data, shortestPathSearchImpl(SearchEngineData &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade, const datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT> &facade,
const std::vector<PhantomNodes> &phantom_nodes_vector, const std::vector<PhantomNodes> &phantom_nodes_vector,
const boost::optional<bool> continue_straight_at_waypoint) const boost::optional<bool> continue_straight_at_waypoint)
{ {
InternalRouteResult raw_route_data; InternalRouteResult raw_route_data;
const bool allow_uturn_at_waypoint = const bool allow_uturn_at_waypoint =
@ -351,7 +320,7 @@ shortestPathSearch(SearchEngineData &engine_working_data,
} }
else else
{ {
Search(facade, search(facade,
forward_heap, forward_heap,
reverse_heap, reverse_heap,
forward_core_heap, forward_core_heap,
@ -503,6 +472,27 @@ shortestPathSearch(SearchEngineData &engine_working_data,
return raw_route_data; return raw_route_data;
} }
}
InternalRouteResult
shortestPathSearch(SearchEngineData &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
const std::vector<PhantomNodes> &phantom_nodes_vector,
const boost::optional<bool> continue_straight_at_waypoint)
{
return shortestPathSearchImpl(
engine_working_data, facade, phantom_nodes_vector, continue_straight_at_waypoint);
}
InternalRouteResult
shortestPathSearch(SearchEngineData &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CoreCH> &facade,
const std::vector<PhantomNodes> &phantom_nodes_vector,
const boost::optional<bool> continue_straight_at_waypoint)
{
return shortestPathSearchImpl(
engine_working_data, facade, phantom_nodes_vector, continue_straight_at_waypoint);
}
} // namespace routing_algorithms } // namespace routing_algorithms
} // namespace engine } // namespace engine

View File

@ -17,8 +17,15 @@ namespace osrm
// Pimpl idiom // Pimpl idiom
OSRM::OSRM(engine::EngineConfig &config) OSRM::OSRM(engine::EngineConfig &config)
: engine_(std::make_unique<engine::Engine<engine::algorithm::CH>>(config))
{ {
if (engine::Engine<engine::algorithm::CoreCH>::CheckCompability(config))
{
engine_ = std::make_unique<engine::Engine<engine::algorithm::CoreCH>>(config);
}
else
{
engine_ = std::make_unique<engine::Engine<engine::algorithm::CH>>(config);
}
} }
OSRM::~OSRM() = default; OSRM::~OSRM() = default;
OSRM::OSRM(OSRM &&) noexcept = default; OSRM::OSRM(OSRM &&) noexcept = default;

View File

@ -278,6 +278,16 @@ class MockAlgorithmDataFacade<engine::algorithm::CH>
{ {
return SPECIAL_EDGEID; return SPECIAL_EDGEID;
} }
};
template <>
class MockAlgorithmDataFacade<engine::algorithm::CoreCH>
: public engine::datafacade::AlgorithmDataFacade<engine::algorithm::CoreCH>
{
private:
EdgeData foo;
public:
bool IsCoreNode(const NodeID /* id */) const override { return false; } bool IsCoreNode(const NodeID /* id */) const override { return false; }
std::size_t GetCoreSize() const override { return 0; } std::size_t GetCoreSize() const override { return 0; }
}; };
@ -287,6 +297,14 @@ class MockDataFacade final : public MockBaseDataFacade, public MockAlgorithmData
{ {
}; };
template <>
class MockDataFacade<engine::algorithm::CoreCH> final
: public MockBaseDataFacade,
public MockAlgorithmDataFacade<engine::algorithm::CH>,
public MockAlgorithmDataFacade<engine::algorithm::CoreCH>
{
};
} // ns test } // ns test
} // ns osrm } // ns osrm