copy dummy cache over implement retrievePackedPathFromSearchSpace calculate packed_path_from_source_to_middle debugging the retrievePackedPathFromSearchSpace function implementation adding in packed_path_from_source_to_middle cache is partway working unpack path and get duration that way the computeDurationForEdge method comment out cache clean up the code move vector creation and allocation to outside of loop hack to not return vectors on facade.GetUncompressedForwardDurations and facade.GetUncompressedReverseDurations clean up hack add exclude_index to cache key clearing cache with timestamp rebase against vectors->range pr swapped out unordered_map cache with a boost_lru implementation calculation for cache size cleaned up comment about cache size calculations unit tests cache uses unsigned char for exclude index clean up cache and unit tests pass in a hashed key to the threadlocal cache 500 mb threadlocal 2 t fixes and a rebase correct calculation
759 lines
27 KiB
C++
759 lines
27 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 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;
|
|
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;
|
|
|
|
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;
|
|
std::size_t m_exclude_index;
|
|
unsigned m_timestamp;
|
|
|
|
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_exclude_index = exclude_index;
|
|
|
|
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:
|
|
std::size_t GetTimestamp() const { return m_timestamp; }
|
|
std::size_t GetExcludeIndex() const { return m_exclude_index; }
|
|
|
|
// 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,
|
|
unsigned timestamp)
|
|
: allocator(std::move(allocator_)), m_timestamp(timestamp)
|
|
{
|
|
InitializeInternalPointers(allocator->GetIndex(), 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];
|
|
}
|
|
|
|
NodeForwardRange GetUncompressedForwardGeometry(const EdgeID id) const override final
|
|
{
|
|
return segment_data.GetForwardGeometry(id);
|
|
}
|
|
|
|
NodeReverseRange GetUncompressedReverseGeometry(const EdgeID id) const override final
|
|
{
|
|
return segment_data.GetReverseGeometry(id);
|
|
}
|
|
|
|
DurationForwardRange GetUncompressedForwardDurations(const EdgeID id) const override final
|
|
{
|
|
return segment_data.GetForwardDurations(id);
|
|
}
|
|
|
|
DurationReverseRange GetUncompressedReverseDurations(const EdgeID id) const override final
|
|
{
|
|
return segment_data.GetReverseDurations(id);
|
|
}
|
|
|
|
WeightForwardRange GetUncompressedForwardWeights(const EdgeID id) const override final
|
|
{
|
|
return segment_data.GetForwardWeights(id);
|
|
}
|
|
|
|
WeightReverseRange GetUncompressedReverseWeights(const EdgeID 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 EdgeID 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 EdgeID id) const override final
|
|
{
|
|
return segment_data.GetReverseDatasources(id);
|
|
}
|
|
|
|
TurnPenalty GetWeightPenaltyForEdgeID(const EdgeID id) const override final
|
|
{
|
|
BOOST_ASSERT(m_turn_weight_penalties.size() > id);
|
|
return m_turn_weight_penalties[id];
|
|
}
|
|
|
|
TurnPenalty GetDurationPenaltyForEdgeID(const EdgeID 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,
|
|
unsigned timestamp)
|
|
: ContiguousInternalMemoryDataFacadeBase(allocator, metric_name, exclude_index, timestamp),
|
|
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 n) const override final
|
|
{
|
|
return query_graph.GetOutDegree(n);
|
|
}
|
|
|
|
EdgeRange GetAdjacentEdgeRange(const NodeID node) const override final
|
|
{
|
|
return query_graph.GetAdjacentEdgeRange(node);
|
|
}
|
|
|
|
EdgeWeight GetNodeWeight(const NodeID node) const override final
|
|
{
|
|
return query_graph.GetNodeWeight(node);
|
|
}
|
|
|
|
EdgeDuration GetNodeDuration(const NodeID node) const override final
|
|
{
|
|
return query_graph.GetNodeDuration(node);
|
|
}
|
|
|
|
bool IsForwardEdge(const NodeID node) const override final
|
|
{
|
|
return query_graph.IsForwardEdge(node);
|
|
}
|
|
|
|
bool IsBackwardEdge(const NodeID node) const override final
|
|
{
|
|
return query_graph.IsBackwardEdge(node);
|
|
}
|
|
|
|
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 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,
|
|
unsigned timestamp)
|
|
: ContiguousInternalMemoryDataFacadeBase(allocator, metric_name, exclude_index, timestamp),
|
|
ContiguousInternalMemoryAlgorithmDataFacade<MLD>(allocator, metric_name, exclude_index)
|
|
{
|
|
}
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif // CONTIGUOUS_INTERNALMEM_DATAFACADE_HPP
|