osrm-backend/include/engine/datafacade/contiguous_internalmem_datafacade.hpp
2018-04-04 12:38:40 +02:00

1184 lines
51 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 "customizer/edge_based_graph.hpp"
#include "extractor/datasources.hpp"
#include "extractor/edge_based_node.hpp"
#include "extractor/intersection_bearings_container.hpp"
#include "extractor/maneuver_override.hpp"
#include "extractor/name_table.hpp"
#include "extractor/node_data_container.hpp"
#include "extractor/packed_osm_ids.hpp"
#include "extractor/profile_properties.hpp"
#include "extractor/segment_data_container.hpp"
#include "extractor/turn_lane_types.hpp"
#include "guidance/turn_bearing.hpp"
#include "guidance/turn_data_container.hpp"
#include "guidance/turn_instruction.hpp"
#include "contractor/query_graph.hpp"
#include "partitioner/cell_storage.hpp"
#include "partitioner/multi_level_partition.hpp"
#include "storage/shared_datatype.hpp"
#include "storage/shared_memory_ownership.hpp"
#include "util/exception.hpp"
#include "util/exception_utils.hpp"
#include "util/filtered_graph.hpp"
#include "util/guidance/bearing_class.hpp"
#include "util/guidance/entry_class.hpp"
#include "util/guidance/turn_lanes.hpp"
#include "util/log.hpp"
#include "util/packed_vector.hpp"
#include "util/range_table.hpp"
#include "util/rectangle.hpp"
#include "util/static_graph.hpp"
#include "util/static_rtree.hpp"
#include "util/typedefs.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;
void InitializeGraphPointer(const storage::DataLayout &data_layout,
char *memory_block,
const std::string& metric_name,
const std::size_t exclude_index)
{
const std::string metric_prefix = "/ch/metrics/" + metric_name;
auto graph_nodes_ptr =
data_layout.GetBlockPtr<GraphNode>(memory_block, metric_prefix + "/contracted_graph/node_array");
auto graph_edges_ptr =
data_layout.GetBlockPtr<GraphEdge>(memory_block, metric_prefix + "/contracted_graph/edge_array");
auto exclude_prefix = metric_prefix + "/exclude/" + std::to_string(exclude_index);
auto filter_block_id = exclude_prefix + "/edge_filter";
auto edge_filter_ptr =
data_layout.GetBlockPtr<util::vector_view<bool>::Word>(memory_block, filter_block_id);
util::vector_view<GraphNode> node_list(
graph_nodes_ptr, data_layout.GetBlockEntries(metric_prefix + "/contracted_graph/node_array"));
util::vector_view<GraphEdge> edge_list(
graph_edges_ptr, data_layout.GetBlockEntries(metric_prefix + "/contracted_graph/edge_array"));
util::vector_view<bool> edge_filter(edge_filter_ptr,
data_layout.GetBlockEntries(filter_block_id));
m_query_graph = QueryGraph({node_list, edge_list}, edge_filter);
}
public:
ContiguousInternalMemoryAlgorithmDataFacade(
std::shared_ptr<ContiguousBlockAllocator> allocator_, const std::string& metric_name, std::size_t exclude_index)
: allocator(std::move(allocator_))
{
InitializeInternalPointers(allocator->GetLayout(), allocator->GetMemory(), metric_name, exclude_index);
}
void InitializeInternalPointers(const storage::DataLayout &data_layout,
char *memory_block,
const std::string& metric_name,
const std::size_t exclude_index)
{
InitializeGraphPointer(data_layout, memory_block, 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 n) const override final
{
return m_query_graph.GetOutDegree(n);
}
NodeID GetTarget(const EdgeID e) const override final { return m_query_graph.GetTarget(e); }
const EdgeData &GetEdgeData(const EdgeID e) const override final
{
return m_query_graph.GetEdgeData(e);
}
EdgeRange GetAdjacentEdgeRange(const NodeID node) const override final
{
return m_query_graph.GetAdjacentEdgeRange(node);
}
// searches for a specific edge
EdgeID FindEdge(const NodeID from, const NodeID to) const override final
{
return m_query_graph.FindEdge(from, to);
}
EdgeID FindEdgeInEitherDirection(const NodeID from, const NodeID to) const override final
{
return m_query_graph.FindEdgeInEitherDirection(from, to);
}
EdgeID
FindEdgeIndicateIfReverse(const NodeID from, const NodeID to, bool &result) const override final
{
return m_query_graph.FindEdgeIndicateIfReverse(from, to, result);
}
EdgeID FindSmallestEdge(const NodeID from,
const NodeID to,
std::function<bool(EdgeData)> filter) const override final
{
return m_query_graph.FindSmallestEdge(from, 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 IndexBlock = util::RangeTable<16, storage::Ownership::View>::BlockT;
using RTreeLeaf = super::RTreeLeaf;
using SharedRTree = util::StaticRTree<RTreeLeaf, storage::Ownership::View>;
using SharedGeospatialQuery = GeospatialQuery<SharedRTree, BaseDataFacade>;
using RTreeNode = SharedRTree::TreeNode;
extractor::ClassData exclude_mask;
std::string m_timestamp;
extractor::ProfileProperties *m_profile_properties;
extractor::Datasources *m_datasources;
std::uint32_t m_check_sum;
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;
std::unique_ptr<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 InitializeProfilePropertiesPointer(const storage::DataLayout &data_layout,
char *memory_block,
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 = data_layout.GetBlockPtr<extractor::ProfileProperties>(
memory_block, "/common/properties");
exclude_mask = m_profile_properties->excludable_classes[exclude_index];
}
void InitializeChecksumPointer(const storage::DataLayout &data_layout, char *memory_block)
{
m_check_sum = *data_layout.GetBlockPtr<std::uint32_t>(memory_block, "/common/connectivity_checksum");
util::Log() << "set checksum: " << m_check_sum;
}
void InitializeRTreePointers(const storage::DataLayout &data_layout, char *memory_block)
{
BOOST_ASSERT_MSG(!m_coordinate_list.empty(), "coordinates must be loaded before r-tree");
const auto file_index_ptr =
data_layout.GetBlockPtr<char>(memory_block, "/common/rtree/file_index_path");
file_index_path = boost::filesystem::path(file_index_ptr);
if (!boost::filesystem::exists(file_index_path))
{
util::Log(logDEBUG) << "Leaf file name " << file_index_path.string();
throw util::exception("Could not load " + file_index_path.string() +
"Is any data loaded into shared memory?" + SOURCE_REF);
}
const auto rtree_ptr =
data_layout.GetBlockPtr<RTreeNode>(memory_block, "/common/rtree/search_tree");
util::vector_view<RTreeNode> search_tree(
rtree_ptr, data_layout.GetBlockEntries("/common/rtree/search_tree"));
const auto rtree_levelstarts_ptr = data_layout.GetBlockPtr<std::uint64_t>(
memory_block, "/common/rtree/search_tree_level_starts");
util::vector_view<std::uint64_t> rtree_level_starts(
rtree_levelstarts_ptr,
data_layout.GetBlockEntries("/common/rtree/search_tree_level_starts"));
m_static_rtree.reset(new SharedRTree{std::move(search_tree),
std::move(rtree_level_starts),
file_index_path,
m_coordinate_list});
m_geospatial_query.reset(
new SharedGeospatialQuery(*m_static_rtree, m_coordinate_list, *this));
}
void InitializeNodeInformationPointers(const storage::DataLayout &layout, char *memory_ptr)
{
const auto coordinate_list_ptr =
layout.GetBlockPtr<util::Coordinate>(memory_ptr, "/common/coordinates");
m_coordinate_list.reset(coordinate_list_ptr, layout.GetBlockEntries("/common/coordinates"));
const auto osmnodeid_ptr = layout.GetBlockPtr<extractor::PackedOSMIDsView::block_type>(
memory_ptr, "/common/osm_node_ids/packed");
m_osmnodeid_list = extractor::PackedOSMIDsView(
util::vector_view<extractor::PackedOSMIDsView::block_type>(
osmnodeid_ptr, layout.GetBlockEntries("/common/osm_node_ids/packed")),
// We (ab)use the number of coordinates here because we know we have the same amount of
// ids
layout.GetBlockEntries("/common/coordinates"));
}
void InitializeEdgeBasedNodeDataInformationPointers(const storage::DataLayout &layout,
char *memory_ptr)
{
const auto edge_based_node_list_ptr =
layout.GetBlockPtr<extractor::EdgeBasedNode>(memory_ptr, "/common/ebg_node_data/nodes");
util::vector_view<extractor::EdgeBasedNode> edge_based_node_data_list(
edge_based_node_list_ptr, layout.GetBlockEntries("/common/ebg_node_data/nodes"));
const auto annotation_data_list_ptr =
layout.GetBlockPtr<extractor::NodeBasedEdgeAnnotation>(
memory_ptr, "/common/ebg_node_data/annotations");
util::vector_view<extractor::NodeBasedEdgeAnnotation> annotation_data(
annotation_data_list_ptr, layout.GetBlockEntries("/common/ebg_node_data/annotations"));
edge_based_node_data = extractor::EdgeBasedNodeDataView(
std::move(edge_based_node_data_list), std::move(annotation_data));
}
void InitializeEdgeInformationPointers(const storage::DataLayout &layout, char *memory_ptr)
{
const auto lane_data_id_ptr =
layout.GetBlockPtr<LaneDataID>(memory_ptr, "/common/turn_data/lane_data_ids");
util::vector_view<LaneDataID> lane_data_ids(
lane_data_id_ptr, layout.GetBlockEntries("/common/turn_data/lane_data_ids"));
const auto turn_instruction_list_ptr = layout.GetBlockPtr<guidance::TurnInstruction>(
memory_ptr, "/common/turn_data/turn_instructions");
util::vector_view<guidance::TurnInstruction> turn_instructions(
turn_instruction_list_ptr,
layout.GetBlockEntries("/common/turn_data/turn_instructions"));
const auto entry_class_id_list_ptr =
layout.GetBlockPtr<EntryClassID>(memory_ptr, "/common/turn_data/entry_class_ids");
util::vector_view<EntryClassID> entry_class_ids(
entry_class_id_list_ptr, layout.GetBlockEntries("/common/turn_data/entry_class_ids"));
const auto pre_turn_bearing_ptr = layout.GetBlockPtr<guidance::TurnBearing>(
memory_ptr, "/common/turn_data/pre_turn_bearings");
util::vector_view<guidance::TurnBearing> pre_turn_bearings(
pre_turn_bearing_ptr, layout.GetBlockEntries("/common/turn_data/pre_turn_bearings"));
const auto post_turn_bearing_ptr = layout.GetBlockPtr<guidance::TurnBearing>(
memory_ptr, "/common/turn_data/post_turn_bearings");
util::vector_view<guidance::TurnBearing> post_turn_bearings(
post_turn_bearing_ptr, layout.GetBlockEntries("/common/turn_data/post_turn_bearings"));
turn_data = guidance::TurnDataView(std::move(turn_instructions),
std::move(lane_data_ids),
std::move(entry_class_ids),
std::move(pre_turn_bearings),
std::move(post_turn_bearings));
}
void InitializeNamePointers(const storage::DataLayout &data_layout, char *memory_block)
{
const auto name_blocks_ptr =
data_layout.GetBlockPtr<extractor::NameTableView::IndexedData::BlockReference>(
memory_block, "/common/names/blocks");
const auto name_values_ptr =
data_layout.GetBlockPtr<extractor::NameTableView::IndexedData::ValueType>(
memory_block, "/common/names/values");
util::vector_view<extractor::NameTableView::IndexedData::BlockReference> blocks(
name_blocks_ptr, data_layout.GetBlockEntries("/common/names/blocks"));
util::vector_view<extractor::NameTableView::IndexedData::ValueType> values(
name_values_ptr, data_layout.GetBlockEntries("/common/names/values"));
extractor::NameTableView::IndexedData index_data_view{std::move(blocks), std::move(values)};
m_name_table = extractor::NameTableView{std::move(index_data_view)};
}
void InitializeTurnLaneDescriptionsPointers(const storage::DataLayout &data_layout,
char *memory_block)
{
auto offsets_ptr =
data_layout.GetBlockPtr<std::uint32_t>(memory_block, "/common/turn_lanes/offsets");
util::vector_view<std::uint32_t> offsets(
offsets_ptr, data_layout.GetBlockEntries("/common/turn_lanes/offsets"));
m_lane_description_offsets = std::move(offsets);
auto masks_ptr = data_layout.GetBlockPtr<extractor::TurnLaneType::Mask>(
memory_block, "/common/turn_lanes/masks");
util::vector_view<extractor::TurnLaneType::Mask> masks(
masks_ptr, data_layout.GetBlockEntries("/common/turn_lanes/masks"));
m_lane_description_masks = std::move(masks);
const auto lane_tupel_id_pair_ptr =
data_layout.GetBlockPtr<util::guidance::LaneTupleIdPair>(memory_block,
"/common/turn_lanes/data");
util::vector_view<util::guidance::LaneTupleIdPair> lane_tupel_id_pair(
lane_tupel_id_pair_ptr, data_layout.GetBlockEntries("/common/turn_lanes/data"));
m_lane_tupel_id_pairs = std::move(lane_tupel_id_pair);
}
void InitializeTurnPenalties(const storage::DataLayout &data_layout, char *memory_block)
{
auto turn_weight_penalties_ptr =
data_layout.GetBlockPtr<TurnPenalty>(memory_block, "/common/turn_penalty/weight");
m_turn_weight_penalties = util::vector_view<TurnPenalty>(
turn_weight_penalties_ptr, data_layout.GetBlockEntries("/common/turn_penalty/weight"));
auto turn_duration_penalties_ptr =
data_layout.GetBlockPtr<TurnPenalty>(memory_block, "/common/turn_penalty/duration");
m_turn_duration_penalties = util::vector_view<TurnPenalty>(
turn_duration_penalties_ptr,
data_layout.GetBlockEntries("/common/turn_penalty/duration"));
}
void InitializeGeometryPointers(const storage::DataLayout &data_layout, char *memory_block)
{
auto geometries_index_ptr =
data_layout.GetBlockPtr<unsigned>(memory_block, "/common/segment_data/index");
util::vector_view<unsigned> geometry_begin_indices(
geometries_index_ptr, data_layout.GetBlockEntries("/common/segment_data/index"));
auto num_entries = data_layout.GetBlockEntries("/common/segment_data/nodes");
auto geometries_node_list_ptr =
data_layout.GetBlockPtr<NodeID>(memory_block, "/common/segment_data/nodes");
util::vector_view<NodeID> geometry_node_list(geometries_node_list_ptr, num_entries);
auto geometries_fwd_weight_list_ptr =
data_layout.GetBlockPtr<extractor::SegmentDataView::SegmentWeightVector::block_type>(
memory_block, "/common/segment_data/forward_weights/packed");
extractor::SegmentDataView::SegmentWeightVector geometry_fwd_weight_list(
util::vector_view<extractor::SegmentDataView::SegmentWeightVector::block_type>(
geometries_fwd_weight_list_ptr,
data_layout.GetBlockEntries("/common/segment_data/forward_weights/packed")),
num_entries);
auto geometries_rev_weight_list_ptr =
data_layout.GetBlockPtr<extractor::SegmentDataView::SegmentWeightVector::block_type>(
memory_block, "/common/segment_data/reverse_weights/packed");
extractor::SegmentDataView::SegmentWeightVector geometry_rev_weight_list(
util::vector_view<extractor::SegmentDataView::SegmentWeightVector::block_type>(
geometries_rev_weight_list_ptr,
data_layout.GetBlockEntries("/common/segment_data/reverse_weights/packed")),
num_entries);
auto geometries_fwd_duration_list_ptr =
data_layout.GetBlockPtr<extractor::SegmentDataView::SegmentDurationVector::block_type>(
memory_block, "/common/segment_data/forward_durations/packed");
extractor::SegmentDataView::SegmentDurationVector geometry_fwd_duration_list(
util::vector_view<extractor::SegmentDataView::SegmentDurationVector::block_type>(
geometries_fwd_duration_list_ptr,
data_layout.GetBlockEntries("/common/segment_data/forward_durations/packed")),
num_entries);
auto geometries_rev_duration_list_ptr =
data_layout.GetBlockPtr<extractor::SegmentDataView::SegmentDurationVector::block_type>(
memory_block, "/common/segment_data/reverse_durations/packed");
extractor::SegmentDataView::SegmentDurationVector geometry_rev_duration_list(
util::vector_view<extractor::SegmentDataView::SegmentDurationVector::block_type>(
geometries_rev_duration_list_ptr,
data_layout.GetBlockEntries("/common/segment_data/reverse_durations/packed")),
num_entries);
auto geometries_fwd_datasources_list_ptr = data_layout.GetBlockPtr<DatasourceID>(
memory_block, "/common/segment_data/forward_data_sources");
util::vector_view<DatasourceID> geometry_fwd_datasources_list(
geometries_fwd_datasources_list_ptr,
data_layout.GetBlockEntries("/common/segment_data/forward_data_sources"));
auto geometries_rev_datasources_list_ptr = data_layout.GetBlockPtr<DatasourceID>(
memory_block, "/common/segment_data/reverse_data_sources");
util::vector_view<DatasourceID> geometry_rev_datasources_list(
geometries_rev_datasources_list_ptr,
data_layout.GetBlockEntries("/common/segment_data/reverse_data_sources"));
segment_data = extractor::SegmentDataView{std::move(geometry_begin_indices),
std::move(geometry_node_list),
std::move(geometry_fwd_weight_list),
std::move(geometry_rev_weight_list),
std::move(geometry_fwd_duration_list),
std::move(geometry_rev_duration_list),
std::move(geometry_fwd_datasources_list),
std::move(geometry_rev_datasources_list)};
m_datasources = data_layout.GetBlockPtr<extractor::Datasources>(
memory_block, "/common/data_sources_names");
}
void InitializeIntersectionClassPointers(const storage::DataLayout &data_layout,
char *memory_block)
{
auto bearing_class_id_ptr = data_layout.GetBlockPtr<BearingClassID>(
memory_block, "/common/intersection_bearings/node_to_class_id");
util::vector_view<BearingClassID> bearing_class_id(
bearing_class_id_ptr,
data_layout.GetBlockEntries("/common/intersection_bearings/node_to_class_id"));
auto bearing_values_ptr = data_layout.GetBlockPtr<DiscreteBearing>(
memory_block, "/common/intersection_bearings/bearing_values");
util::vector_view<DiscreteBearing> bearing_values(
bearing_values_ptr,
data_layout.GetBlockEntries("/common/intersection_bearings/bearing_values"));
auto offsets_ptr = data_layout.GetBlockPtr<unsigned>(
memory_block, "/common/intersection_bearings/class_id_to_ranges/block_offsets");
auto blocks_ptr = data_layout.GetBlockPtr<IndexBlock>(
memory_block, "/common/intersection_bearings/class_id_to_ranges/diff_blocks");
util::vector_view<unsigned> bearing_offsets(
offsets_ptr,
data_layout.GetBlockEntries(
"/common/intersection_bearings/class_id_to_ranges/block_offsets"));
util::vector_view<IndexBlock> bearing_blocks(
blocks_ptr,
data_layout.GetBlockEntries(
"/common/intersection_bearings/class_id_to_ranges/diff_blocks"));
util::RangeTable<16, storage::Ownership::View> bearing_range_table(
bearing_offsets, bearing_blocks, static_cast<unsigned>(bearing_values.size()));
intersection_bearings_view = extractor::IntersectionBearingsView{
std::move(bearing_values), std::move(bearing_class_id), std::move(bearing_range_table)};
auto entry_class_ptr = data_layout.GetBlockPtr<util::guidance::EntryClass>(
memory_block, "/common/entry_classes");
util::vector_view<util::guidance::EntryClass> entry_class_table(
entry_class_ptr, data_layout.GetBlockEntries("/common/entry_classes"));
m_entry_class_table = std::move(entry_class_table);
}
void InitializeManeuverOverridePointers(const storage::DataLayout &data_layout,
char *memory_block)
{
auto maneuver_overrides_ptr = data_layout.GetBlockPtr<extractor::StorageManeuverOverride>(
memory_block, "/common/maneuver_overrides/overrides");
m_maneuver_overrides = util::vector_view<extractor::StorageManeuverOverride>(
maneuver_overrides_ptr,
data_layout.GetBlockEntries("/common/maneuver_overrides/overrides"));
auto maneuver_override_node_sequences_ptr = data_layout.GetBlockPtr<NodeID>(
memory_block, "/common/maneuver_overrides/node_sequences");
m_maneuver_override_node_sequences = util::vector_view<NodeID>(
maneuver_override_node_sequences_ptr,
data_layout.GetBlockEntries("/common/maneuver_overrides/node_sequences"));
}
void InitializeInternalPointers(const storage::DataLayout &data_layout,
char *memory_block,
const std::string& metric_name,
const std::size_t exclude_index)
{
InitializeChecksumPointer(data_layout, memory_block);
InitializeNodeInformationPointers(data_layout, memory_block);
InitializeEdgeBasedNodeDataInformationPointers(data_layout, memory_block);
InitializeEdgeInformationPointers(data_layout, memory_block);
InitializeTurnPenalties(data_layout, memory_block);
InitializeGeometryPointers(data_layout, memory_block);
InitializeNamePointers(data_layout, memory_block);
InitializeTurnLaneDescriptionsPointers(data_layout, memory_block);
InitializeProfilePropertiesPointer(data_layout, memory_block, metric_name, exclude_index);
InitializeRTreePointers(data_layout, memory_block);
InitializeIntersectionClassPointers(data_layout, memory_block);
InitializeManeuverOverridePointers(data_layout, memory_block);
}
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->GetLayout(), allocator->GetMemory(), metric_name, exclude_index);
}
// node and edge information access
util::Coordinate GetCoordinateOfNode(const NodeID id) const override final
{
return m_coordinate_list[id];
}
OSMNodeID GetOSMNodeIDOfNode(const NodeID id) const override final
{
return m_osmnodeid_list[id];
}
std::vector<NodeID> GetUncompressedForwardGeometry(const EdgeID id) const override final
{
auto range = segment_data.GetForwardGeometry(id);
return std::vector<NodeID>{range.begin(), range.end()};
}
virtual std::vector<NodeID> GetUncompressedReverseGeometry(const EdgeID id) const override final
{
auto range = segment_data.GetReverseGeometry(id);
return std::vector<NodeID>{range.begin(), range.end()};
}
virtual std::vector<EdgeWeight>
GetUncompressedForwardDurations(const EdgeID id) const override final
{
auto range = segment_data.GetForwardDurations(id);
return std::vector<EdgeWeight>{range.begin(), range.end()};
}
virtual std::vector<EdgeWeight>
GetUncompressedReverseDurations(const EdgeID id) const override final
{
auto range = segment_data.GetReverseDurations(id);
return std::vector<EdgeWeight>{range.begin(), range.end()};
}
virtual std::vector<EdgeWeight>
GetUncompressedForwardWeights(const EdgeID id) const override final
{
auto range = segment_data.GetForwardWeights(id);
return std::vector<EdgeWeight>{range.begin(), range.end()};
}
virtual std::vector<EdgeWeight>
GetUncompressedReverseWeights(const EdgeID id) const override final
{
auto range = segment_data.GetReverseWeights(id);
return std::vector<EdgeWeight>{range.begin(), range.end()};
}
// Returns the data source ids that were used to supply the edge
// weights.
virtual std::vector<DatasourceID>
GetUncompressedForwardDatasources(const EdgeID id) const override final
{
auto range = segment_data.GetForwardDatasources(id);
return std::vector<DatasourceID>{range.begin(), range.end()};
}
// Returns the data source ids that were used to supply the edge
// weights.
virtual std::vector<DatasourceID>
GetUncompressedReverseDatasources(const EdgeID id) const override final
{
auto range = segment_data.GetReverseDatasources(id);
return std::vector<DatasourceID>{range.begin(), range.end()};
}
virtual TurnPenalty GetWeightPenaltyForEdgeID(const unsigned id) const override final
{
BOOST_ASSERT(m_turn_weight_penalties.size() > id);
return m_turn_weight_penalties[id];
}
virtual TurnPenalty GetDurationPenaltyForEdgeID(const unsigned id) const override final
{
BOOST_ASSERT(m_turn_duration_penalties.size() > id);
return m_turn_duration_penalties[id];
}
osrm::guidance::TurnInstruction
GetTurnInstructionForEdgeID(const EdgeID id) const override final
{
return turn_data.GetTurnInstruction(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 override final
{
BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodesInRange(
input_coordinate, max_distance, approach);
}
std::vector<PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const float 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->NearestPhantomNodesInRange(
input_coordinate, max_distance, bearing, bearing_range, approach);
}
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 override final
{
BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate, approach);
}
std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance,
const Approach approach) const override final
{
BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate, max_distance, approach);
}
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 override final
{
BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate, max_distance, bearing, bearing_range, approach);
}
std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const int bearing,
const int bearing_range,
const Approach approach) const override final
{
BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate, bearing, bearing_range, approach);
}
std::uint32_t GetCheckSum() const override final { return m_check_sum; }
GeometryID GetGeometryIndex(const NodeID id) const override final
{
return edge_based_node_data.GetGeometryID(id);
}
ComponentID GetComponentID(const NodeID id) const override final
{
return edge_based_node_data.GetComponentID(id);
}
extractor::TravelMode GetTravelMode(const NodeID id) const override final
{
return edge_based_node_data.GetTravelMode(id);
}
extractor::ClassData GetClassData(const NodeID id) const override final
{
return edge_based_node_data.GetClassData(id);
}
bool ExcludeNode(const NodeID id) const override final
{
return (edge_based_node_data.GetClassData(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 id) const override final
{
return edge_based_node_data.GetNameID(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) const override final
{
return intersection_bearings_view.GetBearingClass(node);
}
guidance::TurnBearing PreTurnBearing(const EdgeID eid) const override final
{
return turn_data.GetPreTurnBearing(eid);
}
guidance::TurnBearing PostTurnBearing(const EdgeID eid) const override final
{
return turn_data.GetPostTurnBearing(eid);
}
util::guidance::EntryClass GetEntryClass(const EdgeID turn_id) const override final
{
auto entry_class_id = turn_data.GetEntryClassID(turn_id);
return m_entry_class_table.at(entry_class_id);
}
bool HasLaneData(const EdgeID id) const override final { return turn_data.HasLaneData(id); }
util::guidance::LaneTupleIdPair GetLaneData(const EdgeID id) const override final
{
BOOST_ASSERT(HasLaneData(id));
return m_lane_tupel_id_pairs.at(turn_data.GetLaneDataID(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 id) const override final
{
// TODO: can be moved to a data block indexed by GeometryID
return edge_based_node_data.IsLeftHandDriving(id);
}
bool IsSegregated(const NodeID id) const override final
{
return edge_based_node_data.IsSegregated(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(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::DataLayout &data_layout,
char *memory_block,
const std::string& metric_name,
const std::size_t exclude_index)
{
InitializeMLDDataPointers(data_layout, memory_block, metric_name, exclude_index);
InitializeGraphPointer(data_layout, memory_block);
}
void InitializeMLDDataPointers(const storage::DataLayout &data_layout,
char *memory_block,
const std::string& metric_name,
const std::size_t exclude_index)
{
if (data_layout.GetBlockSize("/mld/multilevelpartition/partition") > 0)
{
BOOST_ASSERT(data_layout.GetBlockSize("/mld/multilevelpartition/level_data") > 0);
BOOST_ASSERT(data_layout.GetBlockSize("/mld/multilevelpartition/cell_to_children") > 0);
auto level_data =
data_layout.GetBlockPtr<partitioner::MultiLevelPartitionView::LevelData>(
memory_block, "/mld/multilevelpartition/level_data");
auto mld_partition_ptr = data_layout.GetBlockPtr<PartitionID>(
memory_block, "/mld/multilevelpartition/partition");
auto partition_entries_count =
data_layout.GetBlockEntries("/mld/multilevelpartition/partition");
util::vector_view<PartitionID> partition(mld_partition_ptr, partition_entries_count);
auto mld_chilren_ptr = data_layout.GetBlockPtr<CellID>(
memory_block, "/mld/multilevelpartition/cell_to_children");
auto children_entries_count =
data_layout.GetBlockEntries("/mld/multilevelpartition/cell_to_children");
util::vector_view<CellID> cell_to_children(mld_chilren_ptr, children_entries_count);
mld_partition =
partitioner::MultiLevelPartitionView{level_data, partition, cell_to_children};
}
const auto exclude_prefix = "/mld/metrics/" + metric_name + "/exclude/" + std::to_string(exclude_index);
const auto weights_block_id = exclude_prefix + "/weights";
const auto durations_block_id = exclude_prefix + "/durations";
if (data_layout.GetBlockSize(weights_block_id) > 0)
{
auto mld_cell_weights_ptr =
data_layout.GetBlockPtr<EdgeWeight>(memory_block, weights_block_id);
auto mld_cell_durations_ptr =
data_layout.GetBlockPtr<EdgeDuration>(memory_block, durations_block_id);
auto weight_entries_count = data_layout.GetBlockEntries(weights_block_id);
auto duration_entries_count = data_layout.GetBlockEntries(durations_block_id);
BOOST_ASSERT(weight_entries_count == duration_entries_count);
util::vector_view<EdgeWeight> weights(mld_cell_weights_ptr, weight_entries_count);
util::vector_view<EdgeDuration> durations(mld_cell_durations_ptr,
duration_entries_count);
mld_cell_metric = customizer::CellMetricView{std::move(weights), std::move(durations)};
}
if (data_layout.GetBlockSize("/mld/cellstorage/cells") > 0)
{
auto mld_source_boundary_ptr =
data_layout.GetBlockPtr<NodeID>(memory_block, "/mld/cellstorage/source_boundary");
auto mld_destination_boundary_ptr = data_layout.GetBlockPtr<NodeID>(
memory_block, "/mld/cellstorage/destination_boundary");
auto mld_cells_ptr = data_layout.GetBlockPtr<partitioner::CellStorageView::CellData>(
memory_block, "/mld/cellstorage/cells");
auto mld_cell_level_offsets_ptr = data_layout.GetBlockPtr<std::uint64_t>(
memory_block, "/mld/cellstorage/level_to_cell_offset");
auto source_boundary_entries_count =
data_layout.GetBlockEntries("/mld/cellstorage/source_boundary");
auto destination_boundary_entries_count =
data_layout.GetBlockEntries("/mld/cellstorage/destination_boundary");
auto cells_entries_counts = data_layout.GetBlockEntries("/mld/cellstorage/cells");
auto cell_level_offsets_entries_count =
data_layout.GetBlockEntries("/mld/cellstorage/level_to_cell_offset");
util::vector_view<NodeID> source_boundary(mld_source_boundary_ptr,
source_boundary_entries_count);
util::vector_view<NodeID> destination_boundary(mld_destination_boundary_ptr,
destination_boundary_entries_count);
util::vector_view<partitioner::CellStorageView::CellData> cells(mld_cells_ptr,
cells_entries_counts);
util::vector_view<std::uint64_t> level_offsets(mld_cell_level_offsets_ptr,
cell_level_offsets_entries_count);
mld_cell_storage = partitioner::CellStorageView{std::move(source_boundary),
std::move(destination_boundary),
std::move(cells),
std::move(level_offsets)};
}
}
void InitializeGraphPointer(const storage::DataLayout &data_layout, char *memory_block)
{
auto graph_nodes_ptr =
data_layout.GetBlockPtr<GraphNode>(memory_block, "/mld/multilevelgraph/node_array");
auto graph_edges_ptr =
data_layout.GetBlockPtr<GraphEdge>(memory_block, "/mld/multilevelgraph/edge_array");
auto graph_node_to_offset_ptr = data_layout.GetBlockPtr<QueryGraph::EdgeOffset>(
memory_block, "/mld/multilevelgraph/node_to_edge_offset");
util::vector_view<GraphNode> node_list(
graph_nodes_ptr, data_layout.GetBlockEntries("/mld/multilevelgraph/node_array"));
util::vector_view<GraphEdge> edge_list(
graph_edges_ptr, data_layout.GetBlockEntries("/mld/multilevelgraph/edge_array"));
util::vector_view<QueryGraph::EdgeOffset> node_to_offset(
graph_node_to_offset_ptr,
data_layout.GetBlockEntries("/mld/multilevelgraph/node_to_edge_offset"));
query_graph =
QueryGraph(std::move(node_list), std::move(edge_list), std::move(node_to_offset));
}
// 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->GetLayout(), allocator->GetMemory(), 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 GetNumberOfEdges() const override final { return query_graph.GetNumberOfEdges(); }
unsigned GetOutDegree(const NodeID n) const override final
{
return query_graph.GetOutDegree(n);
}
NodeID GetTarget(const EdgeID e) const override final { return query_graph.GetTarget(e); }
const EdgeData &GetEdgeData(const EdgeID e) const override final
{
return query_graph.GetEdgeData(e);
}
EdgeRange GetAdjacentEdgeRange(const NodeID node) const override final
{
return query_graph.GetAdjacentEdgeRange(node);
}
EdgeRange GetBorderEdgeRange(const LevelID level, const NodeID node) const override final
{
return query_graph.GetBorderEdgeRange(level, node);
}
// searches for a specific edge
EdgeID FindEdge(const NodeID from, const NodeID to) const override final
{
return query_graph.FindEdge(from, to);
}
};
template <>
class ContiguousInternalMemoryDataFacade<MLD> final
: public ContiguousInternalMemoryDataFacadeBase,
public ContiguousInternalMemoryAlgorithmDataFacade<MLD>
{
private:
public:
ContiguousInternalMemoryDataFacade(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)
{
}
};
}
}
}
#endif // CONTIGUOUS_INTERNALMEM_DATAFACADE_HPP