The data facade interface contains numerous methods for looking up datapoints by identifiers. Many of the parameters use the NodeID or EdgeID types. However, these two identifier types are used for representing three different contexts: 1. Node-based graph edges and nodes 2. Edge-based graph edges and nodes 3. Packed geometries Consider the use of identifier parameters in these examples: --- GetWeightPenaltyForEdgeID(const EdgeID id) <- edge-based edge GetUncompressedForwardWeights(const EdgeID id) <- packed geometry IsLeftHandDriving(const NodeID id) <- edge-based node GetBearingClass(const NodeID node) <- node-based node --- This mixing of contexts within the same interface makes it difficult to understand the relationships and dependencies between the OSRM datasets. For 1. and 2. we continue to use the NodeID and EdgeID types, but change the interface parameter names to identify them as edge-based or node-based graph properties. For 3. we define a new type definition, PackedGeometryID. These changes are to aid with readability. A next step would be to strongly type these definitions, leveraging the Alias template already used for OSM identifiers.
787 lines
29 KiB
C++
787 lines
29 KiB
C++
#ifndef CONTIGUOUS_INTERNALMEM_DATAFACADE_HPP
|
|
#define CONTIGUOUS_INTERNALMEM_DATAFACADE_HPP
|
|
|
|
#include "engine/datafacade/algorithm_datafacade.hpp"
|
|
#include "engine/datafacade/contiguous_block_allocator.hpp"
|
|
#include "engine/datafacade/datafacade_base.hpp"
|
|
|
|
#include "engine/algorithm.hpp"
|
|
#include "engine/approach.hpp"
|
|
#include "engine/geospatial_query.hpp"
|
|
|
|
#include "storage/shared_datatype.hpp"
|
|
#include "storage/shared_memory_ownership.hpp"
|
|
#include "storage/view_factory.hpp"
|
|
|
|
#include "util/exception.hpp"
|
|
#include "util/exception_utils.hpp"
|
|
#include "util/log.hpp"
|
|
|
|
#include <boost/assert.hpp>
|
|
|
|
#include <algorithm>
|
|
#include <cstddef>
|
|
#include <iterator>
|
|
#include <limits>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
namespace osrm
|
|
{
|
|
namespace engine
|
|
{
|
|
namespace datafacade
|
|
{
|
|
|
|
template <typename AlgorithmT> class ContiguousInternalMemoryAlgorithmDataFacade;
|
|
|
|
template <>
|
|
class ContiguousInternalMemoryAlgorithmDataFacade<CH> : public datafacade::AlgorithmDataFacade<CH>
|
|
{
|
|
private:
|
|
using QueryGraph = util::FilteredGraphView<contractor::QueryGraphView>;
|
|
using GraphNode = QueryGraph::NodeArrayEntry;
|
|
using GraphEdge = QueryGraph::EdgeArrayEntry;
|
|
|
|
QueryGraph m_query_graph;
|
|
|
|
// allocator that keeps the allocation data
|
|
std::shared_ptr<ContiguousBlockAllocator> allocator;
|
|
|
|
public:
|
|
ContiguousInternalMemoryAlgorithmDataFacade(
|
|
std::shared_ptr<ContiguousBlockAllocator> allocator_,
|
|
const std::string &metric_name,
|
|
std::size_t exclude_index)
|
|
: allocator(std::move(allocator_))
|
|
{
|
|
InitializeInternalPointers(allocator->GetIndex(), metric_name, exclude_index);
|
|
}
|
|
|
|
void InitializeInternalPointers(const storage::SharedDataIndex &index,
|
|
const std::string &metric_name,
|
|
const std::size_t exclude_index)
|
|
{
|
|
m_query_graph =
|
|
make_filtered_graph_view(index, "/ch/metrics/" + metric_name, exclude_index);
|
|
}
|
|
|
|
// search graph access
|
|
unsigned GetNumberOfNodes() const override final { return m_query_graph.GetNumberOfNodes(); }
|
|
|
|
unsigned GetNumberOfEdges() const override final { return m_query_graph.GetNumberOfEdges(); }
|
|
|
|
unsigned GetOutDegree(const NodeID edge_based_node_id) const override final
|
|
{
|
|
return m_query_graph.GetOutDegree(edge_based_node_id);
|
|
}
|
|
|
|
NodeID GetTarget(const EdgeID edge_based_edge_id) const override final
|
|
{
|
|
return m_query_graph.GetTarget(edge_based_edge_id);
|
|
}
|
|
|
|
const EdgeData &GetEdgeData(const EdgeID edge_based_edge_id) const override final
|
|
{
|
|
return m_query_graph.GetEdgeData(edge_based_edge_id);
|
|
}
|
|
|
|
EdgeRange GetAdjacentEdgeRange(const NodeID edge_based_node_id) const override final
|
|
{
|
|
return m_query_graph.GetAdjacentEdgeRange(edge_based_node_id);
|
|
}
|
|
|
|
// searches for a specific edge
|
|
EdgeID FindEdge(const NodeID edge_based_node_from,
|
|
const NodeID edge_based_node_to) const override final
|
|
{
|
|
return m_query_graph.FindEdge(edge_based_node_from, edge_based_node_to);
|
|
}
|
|
|
|
EdgeID FindEdgeInEitherDirection(const NodeID edge_based_node_from,
|
|
const NodeID edge_based_node_to) const override final
|
|
{
|
|
return m_query_graph.FindEdgeInEitherDirection(edge_based_node_from, edge_based_node_to);
|
|
}
|
|
|
|
EdgeID FindEdgeIndicateIfReverse(const NodeID edge_based_node_from,
|
|
const NodeID edge_based_node_to,
|
|
bool &result) const override final
|
|
{
|
|
return m_query_graph.FindEdgeIndicateIfReverse(
|
|
edge_based_node_from, edge_based_node_to, result);
|
|
}
|
|
|
|
EdgeID FindSmallestEdge(const NodeID edge_based_node_from,
|
|
const NodeID edge_based_node_to,
|
|
std::function<bool(EdgeData)> filter) const override final
|
|
{
|
|
return m_query_graph.FindSmallestEdge(edge_based_node_from, edge_based_node_to, filter);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* This base class implements the Datafacade interface for accessing
|
|
* data that's stored in a single large block of memory (RAM).
|
|
*
|
|
* In this case "internal memory" refers to RAM - as opposed to "external memory",
|
|
* which usually refers to disk.
|
|
*/
|
|
class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
|
{
|
|
private:
|
|
using super = BaseDataFacade;
|
|
using RTreeLeaf = super::RTreeLeaf;
|
|
using SharedRTree = util::StaticRTree<RTreeLeaf, storage::Ownership::View>;
|
|
using SharedGeospatialQuery = GeospatialQuery<SharedRTree, BaseDataFacade>;
|
|
|
|
extractor::ClassData exclude_mask;
|
|
extractor::ProfileProperties *m_profile_properties;
|
|
extractor::Datasources *m_datasources;
|
|
|
|
std::uint32_t m_check_sum;
|
|
StringView m_data_timestamp;
|
|
util::vector_view<util::Coordinate> m_coordinate_list;
|
|
extractor::PackedOSMIDsView m_osmnodeid_list;
|
|
util::vector_view<std::uint32_t> m_lane_description_offsets;
|
|
util::vector_view<extractor::TurnLaneType::Mask> m_lane_description_masks;
|
|
util::vector_view<TurnPenalty> m_turn_weight_penalties;
|
|
util::vector_view<TurnPenalty> m_turn_duration_penalties;
|
|
extractor::SegmentDataView segment_data;
|
|
extractor::EdgeBasedNodeDataView edge_based_node_data;
|
|
guidance::TurnDataView turn_data;
|
|
|
|
util::vector_view<char> m_datasource_name_data;
|
|
util::vector_view<std::size_t> m_datasource_name_offsets;
|
|
util::vector_view<std::size_t> m_datasource_name_lengths;
|
|
util::vector_view<util::guidance::LaneTupleIdPair> m_lane_tupel_id_pairs;
|
|
|
|
util::vector_view<extractor::StorageManeuverOverride> m_maneuver_overrides;
|
|
util::vector_view<NodeID> m_maneuver_override_node_sequences;
|
|
|
|
SharedRTree m_static_rtree;
|
|
std::unique_ptr<SharedGeospatialQuery> m_geospatial_query;
|
|
boost::filesystem::path file_index_path;
|
|
|
|
extractor::IntersectionBearingsView intersection_bearings_view;
|
|
|
|
extractor::NameTableView m_name_table;
|
|
// the look-up table for entry classes. An entry class lists the possibility of entry for all
|
|
// available turns. Such a class id is stored with every edge.
|
|
util::vector_view<util::guidance::EntryClass> m_entry_class_table;
|
|
|
|
// allocator that keeps the allocation data
|
|
std::shared_ptr<ContiguousBlockAllocator> allocator;
|
|
|
|
void InitializeInternalPointers(const storage::SharedDataIndex &index,
|
|
const std::string &metric_name,
|
|
const std::size_t exclude_index)
|
|
{
|
|
// TODO: For multi-metric support we need to have separate exclude classes per metric
|
|
(void)metric_name;
|
|
|
|
m_profile_properties =
|
|
index.GetBlockPtr<extractor::ProfileProperties>("/common/properties");
|
|
|
|
exclude_mask = m_profile_properties->excludable_classes[exclude_index];
|
|
|
|
m_check_sum = *index.GetBlockPtr<std::uint32_t>("/common/connectivity_checksum");
|
|
|
|
m_data_timestamp = make_timestamp_view(index, "/common/timestamp");
|
|
|
|
std::tie(m_coordinate_list, m_osmnodeid_list) =
|
|
make_nbn_data_view(index, "/common/nbn_data");
|
|
|
|
m_static_rtree = make_search_tree_view(index, "/common/rtree");
|
|
m_geospatial_query.reset(
|
|
new SharedGeospatialQuery(m_static_rtree, m_coordinate_list, *this));
|
|
|
|
edge_based_node_data = make_ebn_data_view(index, "/common/ebg_node_data");
|
|
|
|
turn_data = make_turn_data_view(index, "/common/turn_data");
|
|
|
|
m_name_table = make_name_table_view(index, "/common/names");
|
|
|
|
std::tie(m_lane_description_offsets, m_lane_description_masks) =
|
|
make_turn_lane_description_views(index, "/common/turn_lanes");
|
|
m_lane_tupel_id_pairs = make_lane_data_view(index, "/common/turn_lanes");
|
|
|
|
m_turn_weight_penalties = make_turn_weight_view(index, "/common/turn_penalty");
|
|
m_turn_duration_penalties = make_turn_duration_view(index, "/common/turn_penalty");
|
|
|
|
segment_data = make_segment_data_view(index, "/common/segment_data");
|
|
|
|
m_datasources = index.GetBlockPtr<extractor::Datasources>("/common/data_sources_names");
|
|
|
|
intersection_bearings_view =
|
|
make_intersection_bearings_view(index, "/common/intersection_bearings");
|
|
|
|
m_entry_class_table = make_entry_classes_view(index, "/common/entry_classes");
|
|
|
|
std::tie(m_maneuver_overrides, m_maneuver_override_node_sequences) =
|
|
make_maneuver_overrides_views(index, "/common/maneuver_overrides");
|
|
}
|
|
|
|
public:
|
|
// allows switching between process_memory/shared_memory datafacade, based on the type of
|
|
// allocator
|
|
ContiguousInternalMemoryDataFacadeBase(std::shared_ptr<ContiguousBlockAllocator> allocator_,
|
|
const std::string &metric_name,
|
|
const std::size_t exclude_index)
|
|
: allocator(std::move(allocator_))
|
|
{
|
|
InitializeInternalPointers(allocator->GetIndex(), metric_name, exclude_index);
|
|
}
|
|
|
|
// node and edge information access
|
|
util::Coordinate GetCoordinateOfNode(const NodeID node_based_node_id) const override final
|
|
{
|
|
return m_coordinate_list[node_based_node_id];
|
|
}
|
|
|
|
OSMNodeID GetOSMNodeIDOfNode(const NodeID node_based_node_id) const override final
|
|
{
|
|
return m_osmnodeid_list[node_based_node_id];
|
|
}
|
|
|
|
NodeForwardRange GetUncompressedForwardGeometry(const PackedGeometryID id) const override final
|
|
{
|
|
return segment_data.GetForwardGeometry(id);
|
|
}
|
|
|
|
NodeReverseRange GetUncompressedReverseGeometry(const PackedGeometryID id) const override final
|
|
{
|
|
return segment_data.GetReverseGeometry(id);
|
|
}
|
|
|
|
DurationForwardRange
|
|
GetUncompressedForwardDurations(const PackedGeometryID id) const override final
|
|
{
|
|
return segment_data.GetForwardDurations(id);
|
|
}
|
|
|
|
DurationReverseRange
|
|
GetUncompressedReverseDurations(const PackedGeometryID id) const override final
|
|
{
|
|
return segment_data.GetReverseDurations(id);
|
|
}
|
|
|
|
WeightForwardRange GetUncompressedForwardWeights(const PackedGeometryID id) const override final
|
|
{
|
|
return segment_data.GetForwardWeights(id);
|
|
}
|
|
|
|
WeightReverseRange GetUncompressedReverseWeights(const PackedGeometryID id) const override final
|
|
{
|
|
return segment_data.GetReverseWeights(id);
|
|
}
|
|
|
|
// Returns the data source ids that were used to supply the edge
|
|
// weights.
|
|
DatasourceForwardRange
|
|
GetUncompressedForwardDatasources(const PackedGeometryID id) const override final
|
|
{
|
|
return segment_data.GetForwardDatasources(id);
|
|
}
|
|
|
|
// Returns the data source ids that were used to supply the edge
|
|
// weights.
|
|
DatasourceReverseRange
|
|
GetUncompressedReverseDatasources(const PackedGeometryID id) const override final
|
|
{
|
|
return segment_data.GetReverseDatasources(id);
|
|
}
|
|
|
|
TurnPenalty GetWeightPenaltyForEdgeID(const EdgeID edge_based_edge_id) const override final
|
|
{
|
|
BOOST_ASSERT(m_turn_weight_penalties.size() > edge_based_edge_id);
|
|
return m_turn_weight_penalties[edge_based_edge_id];
|
|
}
|
|
|
|
TurnPenalty GetDurationPenaltyForEdgeID(const EdgeID edge_based_edge_id) const override final
|
|
{
|
|
BOOST_ASSERT(m_turn_duration_penalties.size() > edge_based_edge_id);
|
|
return m_turn_duration_penalties[edge_based_edge_id];
|
|
}
|
|
|
|
osrm::guidance::TurnInstruction
|
|
GetTurnInstructionForEdgeID(const EdgeID edge_based_edge_id) const override final
|
|
{
|
|
return turn_data.GetTurnInstruction(edge_based_edge_id);
|
|
}
|
|
|
|
std::vector<RTreeLeaf> GetEdgesInBox(const util::Coordinate south_west,
|
|
const util::Coordinate north_east) const override final
|
|
{
|
|
BOOST_ASSERT(m_geospatial_query.get());
|
|
const util::RectangleInt2D bbox{
|
|
south_west.lon, north_east.lon, south_west.lat, north_east.lat};
|
|
return m_geospatial_query->Search(bbox);
|
|
}
|
|
|
|
std::vector<PhantomNodeWithDistance>
|
|
NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
|
|
const float max_distance,
|
|
const Approach approach,
|
|
const bool use_all_edges) const override final
|
|
{
|
|
BOOST_ASSERT(m_geospatial_query.get());
|
|
|
|
return m_geospatial_query->NearestPhantomNodesInRange(
|
|
input_coordinate, max_distance, approach, use_all_edges);
|
|
}
|
|
|
|
std::vector<PhantomNodeWithDistance>
|
|
NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
|
|
const float max_distance,
|
|
const int bearing,
|
|
const int bearing_range,
|
|
const Approach approach,
|
|
const bool use_all_edges) const override final
|
|
{
|
|
BOOST_ASSERT(m_geospatial_query.get());
|
|
|
|
return m_geospatial_query->NearestPhantomNodesInRange(
|
|
input_coordinate, max_distance, bearing, bearing_range, approach, use_all_edges);
|
|
}
|
|
|
|
std::vector<PhantomNodeWithDistance>
|
|
NearestPhantomNodes(const util::Coordinate input_coordinate,
|
|
const unsigned max_results,
|
|
const Approach approach) const override final
|
|
{
|
|
BOOST_ASSERT(m_geospatial_query.get());
|
|
|
|
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results, approach);
|
|
}
|
|
|
|
std::vector<PhantomNodeWithDistance>
|
|
NearestPhantomNodes(const util::Coordinate input_coordinate,
|
|
const unsigned max_results,
|
|
const double max_distance,
|
|
const Approach approach) const override final
|
|
{
|
|
BOOST_ASSERT(m_geospatial_query.get());
|
|
|
|
return m_geospatial_query->NearestPhantomNodes(
|
|
input_coordinate, max_results, max_distance, approach);
|
|
}
|
|
|
|
std::vector<PhantomNodeWithDistance>
|
|
NearestPhantomNodes(const util::Coordinate input_coordinate,
|
|
const unsigned max_results,
|
|
const int bearing,
|
|
const int bearing_range,
|
|
const Approach approach) const override final
|
|
{
|
|
BOOST_ASSERT(m_geospatial_query.get());
|
|
|
|
return m_geospatial_query->NearestPhantomNodes(
|
|
input_coordinate, max_results, bearing, bearing_range, approach);
|
|
}
|
|
|
|
std::vector<PhantomNodeWithDistance>
|
|
NearestPhantomNodes(const util::Coordinate input_coordinate,
|
|
const unsigned max_results,
|
|
const double max_distance,
|
|
const int bearing,
|
|
const int bearing_range,
|
|
const Approach approach) const override final
|
|
{
|
|
BOOST_ASSERT(m_geospatial_query.get());
|
|
|
|
return m_geospatial_query->NearestPhantomNodes(
|
|
input_coordinate, max_results, max_distance, bearing, bearing_range, approach);
|
|
}
|
|
|
|
std::pair<PhantomNode, PhantomNode>
|
|
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
|
const Approach approach,
|
|
const bool use_all_edges) const override final
|
|
{
|
|
BOOST_ASSERT(m_geospatial_query.get());
|
|
|
|
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
|
|
input_coordinate, approach, use_all_edges);
|
|
}
|
|
|
|
std::pair<PhantomNode, PhantomNode>
|
|
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
|
const double max_distance,
|
|
const Approach approach,
|
|
const bool use_all_edges) const override final
|
|
{
|
|
BOOST_ASSERT(m_geospatial_query.get());
|
|
|
|
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
|
|
input_coordinate, max_distance, approach, use_all_edges);
|
|
}
|
|
|
|
std::pair<PhantomNode, PhantomNode>
|
|
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
|
const double max_distance,
|
|
const int bearing,
|
|
const int bearing_range,
|
|
const Approach approach,
|
|
const bool use_all_edges) const override final
|
|
{
|
|
BOOST_ASSERT(m_geospatial_query.get());
|
|
|
|
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
|
|
input_coordinate, max_distance, bearing, bearing_range, approach, use_all_edges);
|
|
}
|
|
|
|
std::pair<PhantomNode, PhantomNode>
|
|
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
|
const int bearing,
|
|
const int bearing_range,
|
|
const Approach approach,
|
|
const bool use_all_edges) const override final
|
|
{
|
|
BOOST_ASSERT(m_geospatial_query.get());
|
|
|
|
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
|
|
input_coordinate, bearing, bearing_range, approach, use_all_edges);
|
|
}
|
|
|
|
std::uint32_t GetCheckSum() const override final { return m_check_sum; }
|
|
|
|
std::string GetTimestamp() const override final
|
|
{
|
|
return std::string(m_data_timestamp.begin(), m_data_timestamp.end());
|
|
}
|
|
|
|
GeometryID GetGeometryIndex(const NodeID edge_based_node_id) const override final
|
|
{
|
|
return edge_based_node_data.GetGeometryID(edge_based_node_id);
|
|
}
|
|
|
|
ComponentID GetComponentID(const NodeID edge_based_node_id) const override final
|
|
{
|
|
return edge_based_node_data.GetComponentID(edge_based_node_id);
|
|
}
|
|
|
|
extractor::TravelMode GetTravelMode(const NodeID edge_based_node_id) const override final
|
|
{
|
|
return edge_based_node_data.GetTravelMode(edge_based_node_id);
|
|
}
|
|
|
|
extractor::ClassData GetClassData(const NodeID edge_based_node_id) const override final
|
|
{
|
|
return edge_based_node_data.GetClassData(edge_based_node_id);
|
|
}
|
|
|
|
bool ExcludeNode(const NodeID edge_based_node_id) const override final
|
|
{
|
|
return (edge_based_node_data.GetClassData(edge_based_node_id) & exclude_mask) > 0;
|
|
}
|
|
|
|
std::vector<std::string> GetClasses(const extractor::ClassData class_data) const override final
|
|
{
|
|
auto indexes = extractor::getClassIndexes(class_data);
|
|
std::vector<std::string> classes(indexes.size());
|
|
std::transform(indexes.begin(), indexes.end(), classes.begin(), [this](const auto index) {
|
|
return m_profile_properties->GetClassName(index);
|
|
});
|
|
|
|
return classes;
|
|
}
|
|
|
|
NameID GetNameIndex(const NodeID edge_based_node_id) const override final
|
|
{
|
|
return edge_based_node_data.GetNameID(edge_based_node_id);
|
|
}
|
|
|
|
StringView GetNameForID(const NameID id) const override final
|
|
{
|
|
return m_name_table.GetNameForID(id);
|
|
}
|
|
|
|
StringView GetRefForID(const NameID id) const override final
|
|
{
|
|
return m_name_table.GetRefForID(id);
|
|
}
|
|
|
|
StringView GetPronunciationForID(const NameID id) const override final
|
|
{
|
|
return m_name_table.GetPronunciationForID(id);
|
|
}
|
|
|
|
StringView GetDestinationsForID(const NameID id) const override final
|
|
{
|
|
return m_name_table.GetDestinationsForID(id);
|
|
}
|
|
|
|
StringView GetExitsForID(const NameID id) const override final
|
|
{
|
|
return m_name_table.GetExitsForID(id);
|
|
}
|
|
|
|
StringView GetDatasourceName(const DatasourceID id) const override final
|
|
{
|
|
return m_datasources->GetSourceName(id);
|
|
}
|
|
|
|
bool GetContinueStraightDefault() const override final
|
|
{
|
|
return m_profile_properties->continue_straight_at_waypoint;
|
|
}
|
|
|
|
double GetMapMatchingMaxSpeed() const override final
|
|
{
|
|
return m_profile_properties->max_speed_for_map_matching;
|
|
}
|
|
|
|
const char *GetWeightName() const override final { return m_profile_properties->weight_name; }
|
|
|
|
unsigned GetWeightPrecision() const override final
|
|
{
|
|
return m_profile_properties->weight_precision;
|
|
}
|
|
|
|
double GetWeightMultiplier() const override final
|
|
{
|
|
return m_profile_properties->GetWeightMultiplier();
|
|
}
|
|
|
|
util::guidance::BearingClass
|
|
GetBearingClass(const NodeID node_based_node_id) const override final
|
|
{
|
|
return intersection_bearings_view.GetBearingClass(node_based_node_id);
|
|
}
|
|
|
|
guidance::TurnBearing PreTurnBearing(const EdgeID edge_based_edge_id) const override final
|
|
{
|
|
return turn_data.GetPreTurnBearing(edge_based_edge_id);
|
|
}
|
|
guidance::TurnBearing PostTurnBearing(const EdgeID edge_based_edge_id) const override final
|
|
{
|
|
return turn_data.GetPostTurnBearing(edge_based_edge_id);
|
|
}
|
|
|
|
util::guidance::EntryClass GetEntryClass(const EdgeID edge_based_edge_id) const override final
|
|
{
|
|
auto entry_class_id = turn_data.GetEntryClassID(edge_based_edge_id);
|
|
return m_entry_class_table.at(entry_class_id);
|
|
}
|
|
|
|
bool HasLaneData(const EdgeID edge_based_edge_id) const override final
|
|
{
|
|
return turn_data.HasLaneData(edge_based_edge_id);
|
|
}
|
|
|
|
util::guidance::LaneTupleIdPair
|
|
GetLaneData(const EdgeID edge_based_edge_id) const override final
|
|
{
|
|
BOOST_ASSERT(HasLaneData(edge_based_edge_id));
|
|
return m_lane_tupel_id_pairs.at(turn_data.GetLaneDataID(edge_based_edge_id));
|
|
}
|
|
|
|
extractor::TurnLaneDescription
|
|
GetTurnDescription(const LaneDescriptionID lane_description_id) const override final
|
|
{
|
|
if (lane_description_id == INVALID_LANE_DESCRIPTIONID)
|
|
return {};
|
|
else
|
|
return extractor::TurnLaneDescription(
|
|
m_lane_description_masks.begin() + m_lane_description_offsets[lane_description_id],
|
|
m_lane_description_masks.begin() +
|
|
m_lane_description_offsets[lane_description_id + 1]);
|
|
}
|
|
|
|
bool IsLeftHandDriving(const NodeID edge_based_node_id) const override final
|
|
{
|
|
// TODO: can be moved to a data block indexed by GeometryID
|
|
return edge_based_node_data.IsLeftHandDriving(edge_based_node_id);
|
|
}
|
|
|
|
bool IsSegregated(const NodeID edge_based_node_id) const override final
|
|
{
|
|
return edge_based_node_data.IsSegregated(edge_based_node_id);
|
|
}
|
|
|
|
std::vector<extractor::ManeuverOverride>
|
|
GetOverridesThatStartAt(const NodeID edge_based_node_id) const override final
|
|
{
|
|
std::vector<extractor::ManeuverOverride> results;
|
|
|
|
// heterogeneous comparison:
|
|
struct Comp
|
|
{
|
|
bool operator()(const extractor::StorageManeuverOverride &s, NodeID i) const
|
|
{
|
|
return s.start_node < i;
|
|
}
|
|
bool operator()(NodeID i, const extractor::StorageManeuverOverride &s) const
|
|
{
|
|
return i < s.start_node;
|
|
}
|
|
};
|
|
|
|
auto found_range = std::equal_range(
|
|
m_maneuver_overrides.begin(), m_maneuver_overrides.end(), edge_based_node_id, Comp{});
|
|
|
|
std::for_each(found_range.first, found_range.second, [&](const auto &override) {
|
|
std::vector<NodeID> sequence(
|
|
m_maneuver_override_node_sequences.begin() + override.node_sequence_offset_begin,
|
|
m_maneuver_override_node_sequences.begin() + override.node_sequence_offset_end);
|
|
results.push_back(extractor::ManeuverOverride{std::move(sequence),
|
|
override.instruction_node,
|
|
override.override_type,
|
|
override.direction});
|
|
});
|
|
return results;
|
|
}
|
|
};
|
|
|
|
template <typename AlgorithmT> class ContiguousInternalMemoryDataFacade;
|
|
|
|
template <>
|
|
class ContiguousInternalMemoryDataFacade<CH>
|
|
: public ContiguousInternalMemoryDataFacadeBase,
|
|
public ContiguousInternalMemoryAlgorithmDataFacade<CH>
|
|
{
|
|
public:
|
|
ContiguousInternalMemoryDataFacade(const std::shared_ptr<ContiguousBlockAllocator> &allocator,
|
|
const std::string &metric_name,
|
|
const std::size_t exclude_index)
|
|
: ContiguousInternalMemoryDataFacadeBase(allocator, metric_name, exclude_index),
|
|
ContiguousInternalMemoryAlgorithmDataFacade<CH>(allocator, metric_name, exclude_index)
|
|
{
|
|
}
|
|
};
|
|
|
|
template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public AlgorithmDataFacade<MLD>
|
|
{
|
|
// MLD data
|
|
partitioner::MultiLevelPartitionView mld_partition;
|
|
partitioner::CellStorageView mld_cell_storage;
|
|
customizer::CellMetricView mld_cell_metric;
|
|
using QueryGraph = customizer::MultiLevelEdgeBasedGraphView;
|
|
using GraphNode = QueryGraph::NodeArrayEntry;
|
|
using GraphEdge = QueryGraph::EdgeArrayEntry;
|
|
|
|
QueryGraph query_graph;
|
|
|
|
void InitializeInternalPointers(const storage::SharedDataIndex &index,
|
|
const std::string &metric_name,
|
|
const std::size_t exclude_index)
|
|
{
|
|
mld_partition = make_partition_view(index, "/mld/multilevelpartition");
|
|
mld_cell_metric =
|
|
make_filtered_cell_metric_view(index, "/mld/metrics/" + metric_name, exclude_index);
|
|
mld_cell_storage = make_cell_storage_view(index, "/mld/cellstorage");
|
|
query_graph = make_multi_level_graph_view(index, "/mld/multilevelgraph");
|
|
}
|
|
|
|
// allocator that keeps the allocation data
|
|
std::shared_ptr<ContiguousBlockAllocator> allocator;
|
|
|
|
public:
|
|
ContiguousInternalMemoryAlgorithmDataFacade(
|
|
std::shared_ptr<ContiguousBlockAllocator> allocator_,
|
|
const std::string &metric_name,
|
|
const std::size_t exclude_index)
|
|
: allocator(std::move(allocator_))
|
|
{
|
|
InitializeInternalPointers(allocator->GetIndex(), metric_name, exclude_index);
|
|
}
|
|
|
|
const partitioner::MultiLevelPartitionView &GetMultiLevelPartition() const override
|
|
{
|
|
return mld_partition;
|
|
}
|
|
|
|
const partitioner::CellStorageView &GetCellStorage() const override { return mld_cell_storage; }
|
|
|
|
const customizer::CellMetricView &GetCellMetric() const override { return mld_cell_metric; }
|
|
|
|
// search graph access
|
|
unsigned GetNumberOfNodes() const override final { return query_graph.GetNumberOfNodes(); }
|
|
|
|
unsigned GetMaxBorderNodeID() const override final { return query_graph.GetMaxBorderNodeID(); }
|
|
|
|
unsigned GetNumberOfEdges() const override final { return query_graph.GetNumberOfEdges(); }
|
|
|
|
unsigned GetOutDegree(const NodeID edge_based_node_id) const override final
|
|
{
|
|
return query_graph.GetOutDegree(edge_based_node_id);
|
|
}
|
|
|
|
EdgeRange GetAdjacentEdgeRange(const NodeID edge_based_node_id) const override final
|
|
{
|
|
return query_graph.GetAdjacentEdgeRange(edge_based_node_id);
|
|
}
|
|
|
|
EdgeWeight GetNodeWeight(const NodeID edge_based_node_id) const override final
|
|
{
|
|
return query_graph.GetNodeWeight(edge_based_node_id);
|
|
}
|
|
|
|
EdgeDuration GetNodeDuration(const NodeID edge_based_node_id) const override final
|
|
{
|
|
return query_graph.GetNodeDuration(edge_based_node_id);
|
|
}
|
|
|
|
EdgeDistance GetNodeDistance(const NodeID edge_based_node_id) const override final
|
|
{
|
|
return query_graph.GetNodeDistance(edge_based_node_id);
|
|
}
|
|
|
|
bool IsForwardEdge(const NodeID edge_based_node_id) const override final
|
|
{
|
|
return query_graph.IsForwardEdge(edge_based_node_id);
|
|
}
|
|
|
|
bool IsBackwardEdge(const NodeID edge_based_node_id) const override final
|
|
{
|
|
return query_graph.IsBackwardEdge(edge_based_node_id);
|
|
}
|
|
|
|
NodeID GetTarget(const EdgeID edge_based_edge_id) const override final
|
|
{
|
|
return query_graph.GetTarget(edge_based_edge_id);
|
|
}
|
|
|
|
const EdgeData &GetEdgeData(const EdgeID edge_based_edge_id) const override final
|
|
{
|
|
return query_graph.GetEdgeData(edge_based_edge_id);
|
|
}
|
|
|
|
EdgeRange GetBorderEdgeRange(const LevelID level,
|
|
const NodeID edge_based_node_id) const override final
|
|
{
|
|
return query_graph.GetBorderEdgeRange(level, edge_based_node_id);
|
|
}
|
|
|
|
// searches for a specific edge
|
|
EdgeID FindEdge(const NodeID edge_based_node_from,
|
|
const NodeID edge_based_node_to) const override final
|
|
{
|
|
return query_graph.FindEdge(edge_based_node_from, edge_based_node_to);
|
|
}
|
|
};
|
|
|
|
template <>
|
|
class ContiguousInternalMemoryDataFacade<MLD> final
|
|
: public ContiguousInternalMemoryDataFacadeBase,
|
|
public ContiguousInternalMemoryAlgorithmDataFacade<MLD>
|
|
{
|
|
private:
|
|
public:
|
|
ContiguousInternalMemoryDataFacade(const std::shared_ptr<ContiguousBlockAllocator> &allocator,
|
|
const std::string &metric_name,
|
|
const std::size_t exclude_index)
|
|
: ContiguousInternalMemoryDataFacadeBase(allocator, metric_name, exclude_index),
|
|
ContiguousInternalMemoryAlgorithmDataFacade<MLD>(allocator, metric_name, exclude_index)
|
|
{
|
|
}
|
|
};
|
|
} // namespace datafacade
|
|
} // namespace engine
|
|
} // namespace osrm
|
|
|
|
#endif // CONTIGUOUS_INTERNALMEM_DATAFACADE_HPP
|