From a75e16e26b76a1e59a5f08015ddfc9cd071e763d Mon Sep 17 00:00:00 2001 From: Lauren Budorick Date: Fri, 22 Jul 2016 18:23:54 +0200 Subject: [PATCH] Deduplicate foward/reverse geometries Changes the internal representation of compressed geometries to be a single array shared between forward and reverse geometries that can be read in either direction. Includes a change on extractor::OriginalEdgeData to store via_geometry ids that indicate which direction to read the geometry for that edge based edge. Closes #2592 --- include/engine/datafacade/datafacade_base.hpp | 17 +- .../engine/datafacade/internal_datafacade.hpp | 158 +++++++++++++++-- .../engine/datafacade/shared_datafacade.hpp | 165 +++++++++++++++--- include/engine/geospatial_query.hpp | 67 +++---- include/engine/guidance/assemble_geometry.hpp | 20 +-- include/engine/hint.hpp | 4 +- include/engine/phantom_node.hpp | 19 +- .../routing_algorithms/routing_base.hpp | 151 ++++++++-------- .../extractor/compressed_edge_container.hpp | 24 ++- .../extractor/edge_based_graph_factory.hpp | 4 +- include/extractor/edge_based_node.hpp | 13 +- include/extractor/guidance/toolkit.hpp | 2 +- include/extractor/original_edge_data.hpp | 8 +- include/util/shared_memory_vector_wrapper.hpp | 32 ++++ include/util/typedefs.hpp | 17 ++ src/contractor/contractor.cpp | 148 ++++++---------- src/engine/plugins/tile.cpp | 117 ++++++------- src/extractor/compressed_edge_container.cpp | 98 +++++++++-- src/extractor/edge_based_graph_factory.cpp | 47 +++-- src/extractor/extractor.cpp | 3 +- src/storage/storage.cpp | 4 +- unit_tests/mocks/mock_datafacade.hpp | 32 +++- unit_tests/server/parameters_parser.cpp | 44 ++--- unit_tests/util/static_rtree.cpp | 3 +- 24 files changed, 769 insertions(+), 428 deletions(-) diff --git a/include/engine/datafacade/datafacade_base.hpp b/include/engine/datafacade/datafacade_base.hpp index 9dc5f5f7b..7c4b33bfc 100644 --- a/include/engine/datafacade/datafacade_base.hpp +++ b/include/engine/datafacade/datafacade_base.hpp @@ -8,6 +8,7 @@ #include "extractor/external_memory_node.hpp" #include "extractor/guidance/turn_instruction.hpp" #include "extractor/guidance/turn_lane_types.hpp" +#include "extractor/original_edge_data.hpp" #include "engine/phantom_node.hpp" #include "util/exception.hpp" #include "util/guidance/bearing_class.hpp" @@ -74,20 +75,22 @@ class BaseDataFacade virtual util::Coordinate GetCoordinateOfNode(const unsigned id) const = 0; virtual OSMNodeID GetOSMNodeIDOfNode(const unsigned id) const = 0; - virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const = 0; + virtual GeometryID GetGeometryIndexForEdgeID(const unsigned id) const = 0; - virtual void GetUncompressedGeometry(const EdgeID id, - std::vector &result_nodes) const = 0; + virtual std::vector GetUncompressedForwardGeometry(const EdgeID id) const = 0; + + virtual std::vector GetUncompressedReverseGeometry(const EdgeID id) const = 0; // Gets the weight values for each segment in an uncompressed geometry. // Should always be 1 shorter than GetUncompressedGeometry - virtual void GetUncompressedWeights(const EdgeID id, - std::vector &result_weights) const = 0; + virtual std::vector GetUncompressedForwardWeights(const EdgeID id) const = 0; + + virtual std::vector GetUncompressedReverseWeights(const EdgeID id) const = 0; // Returns the data source ids that were used to supply the edge // weights. Will return an empty array when only the base profile is used. - virtual void GetUncompressedDatasources(const EdgeID id, - std::vector &data_sources) const = 0; + virtual std::vector GetUncompressedForwardDatasources(const EdgeID id) const = 0; + virtual std::vector GetUncompressedReverseDatasources(const EdgeID id) const = 0; // Gets the name of a datasource virtual std::string GetDatasourceName(const uint8_t datasource_name_id) const = 0; diff --git a/include/engine/datafacade/internal_datafacade.hpp b/include/engine/datafacade/internal_datafacade.hpp index 9cf9df259..3f1e9d0ba 100644 --- a/include/engine/datafacade/internal_datafacade.hpp +++ b/include/engine/datafacade/internal_datafacade.hpp @@ -76,7 +76,7 @@ class InternalDataFacade final : public BaseDataFacade util::ShM::vector m_coordinate_list; util::PackedVector m_osmnodeid_list; - util::ShM::vector m_via_node_list; + util::ShM::vector m_via_geometry_list; util::ShM::vector m_name_ID_list; util::ShM::vector m_turn_instruction_list; util::ShM::vector m_lane_data_id; @@ -189,7 +189,7 @@ class InternalDataFacade final : public BaseDataFacade boost::filesystem::ifstream edges_input_stream(edges_file, std::ios::binary); unsigned number_of_edges = 0; edges_input_stream.read((char *)&number_of_edges, sizeof(unsigned)); - m_via_node_list.resize(number_of_edges); + m_via_geometry_list.resize(number_of_edges); m_name_ID_list.resize(number_of_edges); m_turn_instruction_list.resize(number_of_edges); m_lane_data_id.resize(number_of_edges); @@ -201,7 +201,7 @@ class InternalDataFacade final : public BaseDataFacade { edges_input_stream.read((char *)&(current_edge_data), sizeof(extractor::OriginalEdgeData)); - m_via_node_list[i] = current_edge_data.via_node; + m_via_geometry_list[i] = current_edge_data.via_geometry; m_name_ID_list[i] = current_edge_data.name_id; m_turn_instruction_list[i] = current_edge_data.turn_instruction; m_lane_data_id[i] = current_edge_data.lane_data_id; @@ -670,9 +670,9 @@ class InternalDataFacade final : public BaseDataFacade return GetNameForID(name_id + 1); } - virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const override final + virtual GeometryID GetGeometryIndexForEdgeID(const unsigned id) const override final { - return m_via_node_list.at(id); + return m_via_geometry_list.at(id); } virtual std::size_t GetCoreSize() const override final { return m_is_core_node.size(); } @@ -689,47 +689,128 @@ class InternalDataFacade final : public BaseDataFacade } } - virtual void GetUncompressedGeometry(const EdgeID id, - std::vector &result_nodes) const override final + virtual std::vector GetUncompressedForwardGeometry(const EdgeID id) const override final { + /* + * NodeID's for geometries are stored in one place for + * both forward and reverse segments along the same bi- + * directional edge. The m_geometry_indices stores + * refences to where to find the beginning of the bi- + * directional edge in the m_geometry_list vector. + * */ const unsigned begin = m_geometry_indices.at(id); const unsigned end = m_geometry_indices.at(id + 1); - result_nodes.clear(); + std::vector result_nodes; + result_nodes.reserve(end - begin); + std::for_each(m_geometry_list.begin() + begin, m_geometry_list.begin() + end, [&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge) { result_nodes.emplace_back(edge.node_id); }); + + return result_nodes; } - virtual void - GetUncompressedWeights(const EdgeID id, - std::vector &result_weights) const override final + virtual std::vector GetUncompressedReverseGeometry(const EdgeID id) const override final { + /* + * NodeID's for geometries are stored in one place for + * both forward and reverse segments along the same bi- + * directional edge. The m_geometry_indices stores + * refences to where to find the beginning of the bi- + * directional edge in the m_geometry_list vector. + * */ const unsigned begin = m_geometry_indices.at(id); const unsigned end = m_geometry_indices.at(id + 1); - result_weights.clear(); + std::vector result_nodes; + + result_nodes.reserve(end - begin); + + std::for_each(m_geometry_list.rbegin() + (m_geometry_list.size() - end), + m_geometry_list.rbegin() + (m_geometry_list.size() - begin), + [&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge) { + result_nodes.emplace_back(edge.node_id); + }); + + return result_nodes; + } + + virtual std::vector + GetUncompressedForwardWeights(const EdgeID id) const override final + { + /* + * EdgeWeights's for geometries are stored in one place for + * both forward and reverse segments along the same bi- + * directional edge. The m_geometry_indices stores + * refences to where to find the beginning of the bi- + * directional edge in the m_geometry_list vector. For + * forward weights of bi-directional edges, edges 2 to + * n of that edge need to be read. + */ + const unsigned begin = m_geometry_indices.at(id) + 1; + const unsigned end = m_geometry_indices.at(id + 1); + + std::vector result_weights; result_weights.reserve(end - begin); + std::for_each(m_geometry_list.begin() + begin, m_geometry_list.begin() + end, [&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge) { - result_weights.emplace_back(edge.weight); + result_weights.emplace_back(edge.forward_weight); }); + + return result_weights; + } + + virtual std::vector + GetUncompressedReverseWeights(const EdgeID id) const override final + { + /* + * EdgeWeights for geometries are stored in one place for + * both forward and reverse segments along the same bi- + * directional edge. The m_geometry_indices stores + * refences to where to find the beginning of the bi- + * directional edge in the m_geometry_list vector. For + * reverse weights of bi-directional edges, edges 1 to + * n-1 of that edge need to be read in reverse. + */ + const unsigned begin = m_geometry_indices.at(id); + const unsigned end = m_geometry_indices.at(id + 1) - 1; + + std::vector result_weights; + result_weights.reserve(end - begin); + + std::for_each(m_geometry_list.rbegin() + (m_geometry_list.size() - end), + m_geometry_list.rbegin() + (m_geometry_list.size() - begin), + [&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge) { + result_weights.emplace_back(edge.reverse_weight); + }); + + return result_weights; } // Returns the data source ids that were used to supply the edge // weights. - virtual void - GetUncompressedDatasources(const EdgeID id, - std::vector &result_datasources) const override final + virtual std::vector + GetUncompressedForwardDatasources(const EdgeID id) const override final { - const unsigned begin = m_geometry_indices.at(id); + /* + * Data sources for geometries are stored in one place for + * both forward and reverse segments along the same bi- + * directional edge. The m_geometry_indices stores + * refences to where to find the beginning of the bi- + * directional edge in the m_geometry_list vector. For + * forward datasources of bi-directional edges, edges 2 to + * n of that edge need to be read. + */ + const unsigned begin = m_geometry_indices.at(id) + 1; const unsigned end = m_geometry_indices.at(id + 1); - result_datasources.clear(); + std::vector result_datasources; result_datasources.reserve(end - begin); // If there was no datasource info, return an array of 0's. @@ -747,6 +828,47 @@ class InternalDataFacade final : public BaseDataFacade m_datasource_list.begin() + end, [&](const uint8_t &datasource_id) { result_datasources.push_back(datasource_id); }); } + + return result_datasources; + } + + // Returns the data source ids that were used to supply the edge + // weights. + virtual std::vector + GetUncompressedReverseDatasources(const EdgeID id) const override final + { + /* + * Datasources for geometries are stored in one place for + * both forward and reverse segments along the same bi- + * directional edge. The m_geometry_indices stores + * refences to where to find the beginning of the bi- + * directional edge in the m_geometry_list vector. For + * reverse datasources of bi-directional edges, edges 1 to + * n-1 of that edge need to be read in reverse. + */ + const unsigned begin = m_geometry_indices.at(id); + const unsigned end = m_geometry_indices.at(id + 1) - 1; + + std::vector result_datasources; + result_datasources.reserve(end - begin); + + // If there was no datasource info, return an array of 0's. + if (m_datasource_list.empty()) + { + for (unsigned i = 0; i < end - begin; ++i) + { + result_datasources.push_back(0); + } + } + else + { + std::for_each( + m_datasource_list.rbegin() + (m_datasource_list.size() - end), + m_datasource_list.rbegin() + (m_datasource_list.size() - begin), + [&](const uint8_t &datasource_id) { result_datasources.push_back(datasource_id); }); + } + + return result_datasources; } virtual std::string GetDatasourceName(const uint8_t datasource_name_id) const override final diff --git a/include/engine/datafacade/shared_datafacade.hpp b/include/engine/datafacade/shared_datafacade.hpp index ef2545d8e..4d21bbfe8 100644 --- a/include/engine/datafacade/shared_datafacade.hpp +++ b/include/engine/datafacade/shared_datafacade.hpp @@ -79,7 +79,7 @@ class SharedDataFacade final : public BaseDataFacade util::ShM::vector m_coordinate_list; util::PackedVector m_osmnodeid_list; - util::ShM::vector m_via_node_list; + util::ShM::vector m_via_geometry_list; util::ShM::vector m_name_ID_list; util::ShM::vector m_lane_data_id; util::ShM::vector m_turn_instruction_list; @@ -229,11 +229,12 @@ class SharedDataFacade final : public BaseDataFacade void LoadViaNodeList() { - auto via_node_list_ptr = data_layout->GetBlockPtr( + auto via_geometry_list_ptr = data_layout->GetBlockPtr( shared_memory, storage::SharedDataLayout::VIA_NODE_LIST); - util::ShM::vector via_node_list( - via_node_list_ptr, data_layout->num_entries[storage::SharedDataLayout::VIA_NODE_LIST]); - m_via_node_list = std::move(via_node_list); + util::ShM::vector via_geometry_list( + via_geometry_list_ptr, + data_layout->num_entries[storage::SharedDataLayout::VIA_NODE_LIST]); + m_via_geometry_list = std::move(via_geometry_list); } void LoadNames() @@ -525,40 +526,113 @@ class SharedDataFacade final : public BaseDataFacade return m_osmnodeid_list.at(id); } - virtual void GetUncompressedGeometry(const EdgeID id, - std::vector &result_nodes) const override final + virtual std::vector GetUncompressedForwardGeometry(const EdgeID id) const override final { + /* + * NodeID's for geometries are stored in one place for + * both forward and reverse segments along the same bi- + * directional edge. The m_geometry_indices stores + * refences to where to find the beginning of the bi- + * directional edge in the m_geometry_list vector. For + * forward geometries of bi-directional edges, edges 2 to + * n of that edge need to be read. + */ const unsigned begin = m_geometry_indices.at(id); const unsigned end = m_geometry_indices.at(id + 1); - result_nodes.clear(); + std::vector result_nodes; + result_nodes.reserve(end - begin); + std::for_each(m_geometry_list.begin() + begin, m_geometry_list.begin() + end, [&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge) { result_nodes.emplace_back(edge.node_id); }); + + return result_nodes; } - virtual void - GetUncompressedWeights(const EdgeID id, - std::vector &result_weights) const override final + virtual std::vector GetUncompressedReverseGeometry(const EdgeID id) const override final { - const unsigned begin = m_geometry_indices.at(id); + /* + * NodeID's for geometries are stored in one place for + * both forward and reverse segments along the same bi- + * directional edge. The m_geometry_indices stores + * refences to where to find the beginning of the bi- + * directional edge in the m_geometry_list vector. + * */ + const signed begin = m_geometry_indices.at(id); + const signed end = m_geometry_indices.at(id + 1); + + std::vector result_nodes; + + result_nodes.reserve(end - begin); + + std::for_each(m_geometry_list.rbegin() + (m_geometry_list.size() - end), + m_geometry_list.rbegin() + (m_geometry_list.size() - begin), + [&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge) { + result_nodes.emplace_back(edge.node_id); + }); + + return result_nodes; + } + + virtual std::vector + GetUncompressedForwardWeights(const EdgeID id) const override final + { + /* + * EdgeWeights's for geometries are stored in one place for + * both forward and reverse segments along the same bi- + * directional edge. The m_geometry_indices stores + * refences to where to find the beginning of the bi- + * directional edge in the m_geometry_list vector. + * */ + const unsigned begin = m_geometry_indices.at(id) + 1; const unsigned end = m_geometry_indices.at(id + 1); - result_weights.clear(); + std::vector result_weights; result_weights.reserve(end - begin); + std::for_each(m_geometry_list.begin() + begin, m_geometry_list.begin() + end, [&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge) { - result_weights.emplace_back(edge.weight); + result_weights.emplace_back(edge.forward_weight); }); + + return result_weights; } - virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const override final + virtual std::vector + GetUncompressedReverseWeights(const EdgeID id) const override final { - return m_via_node_list.at(id); + /* + * EdgeWeights for geometries are stored in one place for + * both forward and reverse segments along the same bi- + * directional edge. The m_geometry_indices stores + * refences to where to find the beginning of the bi- + * directional edge in the m_geometry_list vector. For + * reverse weights of bi-directional edges, edges 1 to + * n-1 of that edge need to be read in reverse. + */ + const signed begin = m_geometry_indices.at(id); + const signed end = m_geometry_indices.at(id + 1) - 1; + + std::vector result_weights; + result_weights.reserve(end - begin); + + std::for_each(m_geometry_list.rbegin() + (m_geometry_list.size() - end), + m_geometry_list.rbegin() + (m_geometry_list.size() - begin), + [&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge) { + result_weights.emplace_back(edge.reverse_weight); + }); + + return result_weights; + } + + virtual GeometryID GetGeometryIndexForEdgeID(const unsigned id) const override final + { + return m_via_geometry_list.at(id); } extractor::guidance::TurnInstruction @@ -755,14 +829,22 @@ class SharedDataFacade final : public BaseDataFacade // Returns the data source ids that were used to supply the edge // weights. - virtual void - GetUncompressedDatasources(const EdgeID id, - std::vector &result_datasources) const override final + virtual std::vector + GetUncompressedForwardDatasources(const EdgeID id) const override final { - const unsigned begin = m_geometry_indices.at(id); + /* + * Data sources for geometries are stored in one place for + * both forward and reverse segments along the same bi- + * directional edge. The m_geometry_indices stores + * refences to where to find the beginning of the bi- + * directional edge in the m_geometry_list vector. For + * forward datasources of bi-directional edges, edges 2 to + * n of that edge need to be read. + */ + const unsigned begin = m_geometry_indices.at(id) + 1; const unsigned end = m_geometry_indices.at(id + 1); - result_datasources.clear(); + std::vector result_datasources; result_datasources.reserve(end - begin); // If there was no datasource info, return an array of 0's. @@ -780,6 +862,47 @@ class SharedDataFacade final : public BaseDataFacade m_datasource_list.begin() + end, [&](const uint8_t &datasource_id) { result_datasources.push_back(datasource_id); }); } + + return result_datasources; + } + + // Returns the data source ids that were used to supply the edge + // weights. + virtual std::vector + GetUncompressedReverseDatasources(const EdgeID id) const override final + { + /* + * Datasources for geometries are stored in one place for + * both forward and reverse segments along the same bi- + * directional edge. The m_geometry_indices stores + * refences to where to find the beginning of the bi- + * directional edge in the m_geometry_list vector. For + * reverse datasources of bi-directional edges, edges 1 to + * n-1 of that edge need to be read in reverse. + */ + const unsigned begin = m_geometry_indices.at(id); + const unsigned end = m_geometry_indices.at(id + 1) - 1; + + std::vector result_datasources; + result_datasources.reserve(end - begin); + + // If there was no datasource info, return an array of 0's. + if (m_datasource_list.empty()) + { + for (unsigned i = 0; i < end - begin; ++i) + { + result_datasources.push_back(0); + } + } + else + { + std::for_each( + m_datasource_list.rbegin() + (m_datasource_list.size() - end), + m_datasource_list.rbegin() + (m_datasource_list.size() - begin), + [&](const uint8_t &datasource_id) { result_datasources.push_back(datasource_id); }); + } + + return result_datasources; } virtual std::string GetDatasourceName(const uint8_t datasource_name_id) const override final diff --git a/include/engine/geospatial_query.hpp b/include/engine/geospatial_query.hpp index 1ff56500f..c00a2a11e 100644 --- a/include/engine/geospatial_query.hpp +++ b/include/engine/geospatial_query.hpp @@ -372,35 +372,25 @@ template class GeospatialQuery int forward_offset = 0, forward_weight = 0; int reverse_offset = 0, reverse_weight = 0; - if (data.forward_packed_geometry_id != SPECIAL_EDGEID) + const std::vector forward_weight_vector = datafacade.GetUncompressedForwardWeights(data.packed_geometry_id); + const std::vector reverse_weight_vector = datafacade.GetUncompressedReverseWeights(data.packed_geometry_id); + + for (std::size_t i = 0; i < data.fwd_segment_position; i++) { - std::vector forward_weight_vector; - datafacade.GetUncompressedWeights(data.forward_packed_geometry_id, - forward_weight_vector); - for (std::size_t i = 0; i < data.fwd_segment_position; i++) - { - forward_offset += forward_weight_vector[i]; - } - forward_weight = forward_weight_vector[data.fwd_segment_position]; + forward_offset += forward_weight_vector[i]; } + forward_weight = forward_weight_vector[data.fwd_segment_position]; - if (data.reverse_packed_geometry_id != SPECIAL_EDGEID) + BOOST_ASSERT(data.fwd_segment_position < reverse_weight_vector.size()); + + for (std::size_t i = 0; + i < reverse_weight_vector.size() - data.fwd_segment_position - 1; + i++) { - std::vector reverse_weight_vector; - datafacade.GetUncompressedWeights(data.reverse_packed_geometry_id, - reverse_weight_vector); - - BOOST_ASSERT(data.fwd_segment_position < reverse_weight_vector.size()); - - for (std::size_t i = 0; - i < reverse_weight_vector.size() - data.fwd_segment_position - 1; - i++) - { - reverse_offset += reverse_weight_vector[i]; - } - reverse_weight = - reverse_weight_vector[reverse_weight_vector.size() - data.fwd_segment_position - 1]; + reverse_offset += reverse_weight_vector[i]; } + reverse_weight = + reverse_weight_vector[reverse_weight_vector.size() - data.fwd_segment_position - 1]; ratio = std::min(1.0, std::max(0.0, ratio)); if (data.forward_segment_id.id != SPECIAL_SEGMENTID) @@ -479,31 +469,18 @@ template class GeospatialQuery bool forward_edge_valid = false; bool reverse_edge_valid = false; - if (segment.data.forward_packed_geometry_id != SPECIAL_EDGEID) - { - std::vector forward_weight_vector; - datafacade.GetUncompressedWeights(segment.data.forward_packed_geometry_id, - forward_weight_vector); + const std::vector forward_weight_vector = datafacade.GetUncompressedForwardWeights(segment.data.packed_geometry_id); - if (forward_weight_vector[segment.data.fwd_segment_position] != INVALID_EDGE_WEIGHT) - { - forward_edge_valid = segment.data.forward_segment_id.enabled; - } + if (forward_weight_vector[segment.data.fwd_segment_position] != INVALID_EDGE_WEIGHT) + { + forward_edge_valid = segment.data.forward_segment_id.enabled; } - if (segment.data.reverse_packed_geometry_id != SPECIAL_EDGEID) + const std::vector reverse_weight_vector = datafacade.GetUncompressedReverseWeights(segment.data.packed_geometry_id); + if (reverse_weight_vector[reverse_weight_vector.size() - + segment.data.fwd_segment_position - 1] != INVALID_EDGE_WEIGHT) { - std::vector reverse_weight_vector; - datafacade.GetUncompressedWeights(segment.data.reverse_packed_geometry_id, - reverse_weight_vector); - - BOOST_ASSERT(segment.data.fwd_segment_position < reverse_weight_vector.size()); - - if (reverse_weight_vector[reverse_weight_vector.size() - - segment.data.fwd_segment_position - 1] != INVALID_EDGE_WEIGHT) - { - reverse_edge_valid = segment.data.reverse_segment_id.enabled; - } + reverse_edge_valid = segment.data.reverse_segment_id.enabled; } return std::make_pair(forward_edge_valid, reverse_edge_valid); diff --git a/include/engine/guidance/assemble_geometry.hpp b/include/engine/guidance/assemble_geometry.hpp index fb9e8fa43..09372c9b4 100644 --- a/include/engine/guidance/assemble_geometry.hpp +++ b/include/engine/guidance/assemble_geometry.hpp @@ -45,14 +45,10 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade, // Need to get the node ID preceding the source phantom node // TODO: check if this was traversed in reverse? - std::vector reverse_geometry; - facade.GetUncompressedGeometry(source_node.reverse_packed_geometry_id, reverse_geometry); + const std::vector source_geometry = + facade.GetUncompressedForwardGeometry(source_node.packed_geometry_id); geometry.osm_node_ids.push_back(facade.GetOSMNodeIDOfNode( - reverse_geometry[reverse_geometry.size() - source_node.fwd_segment_position - 1])); - - std::vector forward_datasource_vector; - facade.GetUncompressedDatasources(source_node.forward_packed_geometry_id, - forward_datasource_vector); + source_geometry[source_node.fwd_segment_position])); auto cumulative_distance = 0.; auto current_distance = 0.; @@ -84,8 +80,8 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade, // segment leading to the target node geometry.segment_distances.push_back(cumulative_distance); - std::vector forward_datasources; - facade.GetUncompressedDatasources(target_node.forward_packed_geometry_id, forward_datasources); + const std::vector forward_datasources = + facade.GetUncompressedForwardDatasources(target_node.packed_geometry_id); geometry.annotations.emplace_back( LegGeometry::Annotation{current_distance, @@ -96,10 +92,10 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade, // Need to get the node ID following the destination phantom node // TODO: check if this was traversed in reverse?? - std::vector forward_geometry; - facade.GetUncompressedGeometry(target_node.forward_packed_geometry_id, forward_geometry); + const std::vector target_geometry = + facade.GetUncompressedForwardGeometry(target_node.packed_geometry_id); geometry.osm_node_ids.push_back( - facade.GetOSMNodeIDOfNode(forward_geometry[target_node.fwd_segment_position])); + facade.GetOSMNodeIDOfNode(target_geometry[target_node.fwd_segment_position + 1])); BOOST_ASSERT(geometry.segment_distances.size() == geometry.segment_offsets.size() - 1); BOOST_ASSERT(geometry.locations.size() > geometry.segment_distances.size()); diff --git a/include/engine/hint.hpp b/include/engine/hint.hpp index a5fd860b6..0819cb7ef 100644 --- a/include/engine/hint.hpp +++ b/include/engine/hint.hpp @@ -63,8 +63,8 @@ struct Hint friend std::ostream &operator<<(std::ostream &, const Hint &); }; -static_assert(sizeof(Hint) == 60 + 4, "Hint is bigger than expected"); -constexpr std::size_t ENCODED_HINT_SIZE = 88; +static_assert(sizeof(Hint) == 56 + 4, "Hint is bigger than expected"); +constexpr std::size_t ENCODED_HINT_SIZE = 80; static_assert(ENCODED_HINT_SIZE / 4 * 3 >= sizeof(Hint), "ENCODED_HINT_SIZE does not match size of Hint"); } diff --git a/include/engine/phantom_node.hpp b/include/engine/phantom_node.hpp index df8454a9d..ca0a9698d 100644 --- a/include/engine/phantom_node.hpp +++ b/include/engine/phantom_node.hpp @@ -53,8 +53,7 @@ struct PhantomNode int reverse_weight, int forward_offset, int reverse_offset, - unsigned forward_packed_geometry_id_, - unsigned reverse_packed_geometry_id_, + unsigned packed_geometry_id_, bool is_tiny_component, unsigned component_id, util::Coordinate location, @@ -65,8 +64,7 @@ struct PhantomNode : forward_segment_id(forward_segment_id), reverse_segment_id(reverse_segment_id), name_id(name_id), forward_weight(forward_weight), reverse_weight(reverse_weight), forward_offset(forward_offset), reverse_offset(reverse_offset), - forward_packed_geometry_id(forward_packed_geometry_id_), - reverse_packed_geometry_id(reverse_packed_geometry_id_), + packed_geometry_id(packed_geometry_id_), component{component_id, is_tiny_component}, location(std::move(location)), input_location(std::move(input_location)), fwd_segment_position(fwd_segment_position), forward_travel_mode(forward_travel_mode), backward_travel_mode(backward_travel_mode) @@ -78,7 +76,7 @@ struct PhantomNode reverse_segment_id{SPECIAL_SEGMENTID, false}, name_id(std::numeric_limits::max()), forward_weight(INVALID_EDGE_WEIGHT), reverse_weight(INVALID_EDGE_WEIGHT), forward_offset(0), reverse_offset(0), - forward_packed_geometry_id(SPECIAL_EDGEID), reverse_packed_geometry_id(SPECIAL_EDGEID), + packed_geometry_id(SPECIAL_GEOMETRYID), component{INVALID_COMPONENTID, false}, fwd_segment_position(0), forward_travel_mode(TRAVEL_MODE_INACCESSIBLE), backward_travel_mode(TRAVEL_MODE_INACCESSIBLE) @@ -129,8 +127,7 @@ struct PhantomNode reverse_segment_id{other.reverse_segment_id}, name_id{other.name_id}, forward_weight{forward_weight_}, reverse_weight{reverse_weight_}, forward_offset{forward_offset_}, reverse_offset{reverse_offset_}, - forward_packed_geometry_id{other.forward_packed_geometry_id}, - reverse_packed_geometry_id{other.reverse_packed_geometry_id}, + packed_geometry_id{other.packed_geometry_id}, component{other.component.id, other.component.is_tiny}, location{location_}, input_location{input_location_}, fwd_segment_position{other.fwd_segment_position}, forward_travel_mode{other.forward_travel_mode}, @@ -145,8 +142,7 @@ struct PhantomNode int reverse_weight; int forward_offset; int reverse_offset; - unsigned forward_packed_geometry_id; - unsigned reverse_packed_geometry_id; + unsigned packed_geometry_id; struct ComponentType { std::uint32_t id : 31; @@ -163,7 +159,7 @@ struct PhantomNode extractor::TravelMode backward_travel_mode; }; -static_assert(sizeof(PhantomNode) == 60, "PhantomNode has more padding then expected"); +static_assert(sizeof(PhantomNode) == 56, "PhantomNode has more padding then expected"); using PhantomNodePair = std::pair; @@ -195,8 +191,7 @@ inline std::ostream &operator<<(std::ostream &out, const PhantomNode &pn) << "rev-w: " << pn.reverse_weight << ", " << "fwd-o: " << pn.forward_offset << ", " << "rev-o: " << pn.reverse_offset << ", " - << "fwd_geom: " << pn.forward_packed_geometry_id << ", " - << "rev_geom: " << pn.reverse_packed_geometry_id << ", " + << "geom: " << pn.packed_geometry_id << ", " << "comp: " << pn.component.is_tiny << " / " << pn.component.id << ", " << "pos: " << pn.fwd_segment_position << ", " << "loc: " << pn.location; diff --git a/include/engine/routing_algorithms/routing_base.hpp b/include/engine/routing_algorithms/routing_base.hpp index 1c712dce1..853f35567 100644 --- a/include/engine/routing_algorithms/routing_base.hpp +++ b/include/engine/routing_algorithms/routing_base.hpp @@ -244,80 +244,90 @@ template class BasicRoutingInterface const auto geometry_index = facade.GetGeometryIndexForEdgeID(edge_data.id); std::vector id_vector; - facade.GetUncompressedGeometry(geometry_index, id_vector); - BOOST_ASSERT(id_vector.size() > 0); - std::vector weight_vector; - facade.GetUncompressedWeights(geometry_index, weight_vector); - BOOST_ASSERT(weight_vector.size() > 0); - std::vector datasource_vector; - facade.GetUncompressedDatasources(geometry_index, datasource_vector); - - const auto total_weight = - std::accumulate(weight_vector.begin(), weight_vector.end(), 0); - - BOOST_ASSERT(weight_vector.size() == id_vector.size()); - const bool is_first_segment = unpacked_path.empty(); - - const std::size_t start_index = - (is_first_segment - ? ((start_traversed_in_reverse) - ? id_vector.size() - - phantom_node_pair.source_phantom.fwd_segment_position - 1 - : phantom_node_pair.source_phantom.fwd_segment_position) - : 0); - const std::size_t end_index = id_vector.size(); - - BOOST_ASSERT(start_index >= 0); - BOOST_ASSERT(start_index < end_index); - for (std::size_t i = start_index; i < end_index; ++i) + if (geometry_index.forward) { - unpacked_path.push_back( - PathData{id_vector[i], - name_index, - weight_vector[i], - extractor::guidance::TurnInstruction::NO_TURN(), - {{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID}, - travel_mode, - INVALID_ENTRY_CLASSID, - datasource_vector[i]}); + id_vector = facade.GetUncompressedForwardGeometry(geometry_index.id); + weight_vector = facade.GetUncompressedForwardWeights(geometry_index.id); + datasource_vector = + facade.GetUncompressedForwardDatasources(geometry_index.id); } - BOOST_ASSERT(unpacked_path.size() > 0); - if (facade.hasLaneData(edge_data.id)) - unpacked_path.back().lane_data = facade.GetLaneData(edge_data.id); + else + { + id_vector = facade.GetUncompressedReverseGeometry(geometry_index.id); + weight_vector = facade.GetUncompressedReverseWeights(geometry_index.id); + datasource_vector = + facade.GetUncompressedReverseDatasources(geometry_index.id); + } + BOOST_ASSERT(id_vector.size() > 0); + BOOST_ASSERT(weight_vector.size() > 0); + BOOST_ASSERT(datasource_vector.size() > 0); - unpacked_path.back().entry_classid = facade.GetEntryClassID(edge_data.id); - unpacked_path.back().turn_instruction = turn_instruction; - unpacked_path.back().duration_until_turn += (edge_data.distance - total_weight); - }); + const auto total_weight = + std::accumulate(weight_vector.begin(), weight_vector.end(), 0); - std::size_t start_index = 0, end_index = 0; - std::vector id_vector; - std::vector weight_vector; - std::vector datasource_vector; - const bool is_local_path = (phantom_node_pair.source_phantom.forward_packed_geometry_id == - phantom_node_pair.target_phantom.forward_packed_geometry_id) && - unpacked_path.empty(); + BOOST_ASSERT(weight_vector.size() == id_vector.size() - 1); + const bool is_first_segment = unpacked_path.empty(); - if (target_traversed_in_reverse) - { - facade.GetUncompressedGeometry( - phantom_node_pair.target_phantom.reverse_packed_geometry_id, id_vector); + const std::size_t start_index = + (is_first_segment + ? ((start_traversed_in_reverse) + ? weight_vector.size() - + phantom_node_pair.source_phantom.fwd_segment_position - 1 + : phantom_node_pair.source_phantom.fwd_segment_position) + : 0); + const std::size_t end_index = weight_vector.size(); - facade.GetUncompressedWeights( - phantom_node_pair.target_phantom.reverse_packed_geometry_id, weight_vector); + BOOST_ASSERT(start_index >= 0); + BOOST_ASSERT(start_index < end_index); + for (std::size_t segment_idx = start_index; segment_idx < end_index; ++segment_idx) + { + unpacked_path.push_back( + PathData{id_vector[segment_idx + 1], + name_index, + weight_vector[segment_idx], + extractor::guidance::TurnInstruction::NO_TURN(), + {{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID}, + travel_mode, + INVALID_ENTRY_CLASSID, + datasource_vector[segment_idx]}); + } + BOOST_ASSERT(unpacked_path.size() > 0); + if (facade.hasLaneData(edge_data.id)) + unpacked_path.back().lane_data = facade.GetLaneData(edge_data.id); - facade.GetUncompressedDatasources( - phantom_node_pair.target_phantom.reverse_packed_geometry_id, datasource_vector); + unpacked_path.back().entry_classid = facade.GetEntryClassID(edge_data.id); + unpacked_path.back().turn_instruction = turn_instruction; + unpacked_path.back().duration_until_turn += (edge_data.distance - total_weight); + }); + + std::size_t start_index = 0, end_index = 0; + std::vector id_vector; + std::vector weight_vector; + std::vector datasource_vector; + const bool is_local_path = (phantom_node_pair.source_phantom.packed_geometry_id == + phantom_node_pair.target_phantom.packed_geometry_id) && + unpacked_path.empty(); + + if (target_traversed_in_reverse) + { + id_vector = facade.GetUncompressedReverseGeometry( + phantom_node_pair.target_phantom.packed_geometry_id); + + weight_vector = facade.GetUncompressedReverseWeights( + phantom_node_pair.target_phantom.packed_geometry_id); + + datasource_vector = facade.GetUncompressedReverseDatasources( + phantom_node_pair.target_phantom.packed_geometry_id); if (is_local_path) { start_index = - id_vector.size() - phantom_node_pair.source_phantom.fwd_segment_position - 1; + weight_vector.size() - phantom_node_pair.source_phantom.fwd_segment_position - 1; } end_index = - id_vector.size() - phantom_node_pair.target_phantom.fwd_segment_position - 1; + weight_vector.size() - phantom_node_pair.target_phantom.fwd_segment_position - 1; } else { @@ -326,14 +336,15 @@ template class BasicRoutingInterface start_index = phantom_node_pair.source_phantom.fwd_segment_position; } end_index = phantom_node_pair.target_phantom.fwd_segment_position; - facade.GetUncompressedGeometry( - phantom_node_pair.target_phantom.forward_packed_geometry_id, id_vector); - facade.GetUncompressedWeights( - phantom_node_pair.target_phantom.forward_packed_geometry_id, weight_vector); + id_vector = facade.GetUncompressedForwardGeometry( + phantom_node_pair.target_phantom.packed_geometry_id); - facade.GetUncompressedDatasources( - phantom_node_pair.target_phantom.forward_packed_geometry_id, datasource_vector); + weight_vector = facade.GetUncompressedForwardWeights( + phantom_node_pair.target_phantom.packed_geometry_id); + + datasource_vector = facade.GetUncompressedForwardDatasources( + phantom_node_pair.target_phantom.packed_geometry_id); } // Given the following compressed geometry: @@ -343,20 +354,20 @@ template class BasicRoutingInterface // t: fwd_segment 3 // -> (U, v), (v, w), (w, x) // note that (x, t) is _not_ included but needs to be added later. - for (std::size_t i = start_index; i != end_index; (start_index < end_index ? ++i : --i)) + for (std::size_t segment_idx = start_index; segment_idx != end_index; (start_index < end_index ? ++segment_idx : --segment_idx)) { - BOOST_ASSERT(i < id_vector.size()); + BOOST_ASSERT(segment_idx < id_vector.size() - 1); BOOST_ASSERT(phantom_node_pair.target_phantom.forward_travel_mode > 0); unpacked_path.push_back(PathData{ - id_vector[i], + id_vector[start_index < end_index ? segment_idx + 1 : segment_idx - 1], phantom_node_pair.target_phantom.name_id, - weight_vector[i], + weight_vector[segment_idx], extractor::guidance::TurnInstruction::NO_TURN(), {{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID}, target_traversed_in_reverse ? phantom_node_pair.target_phantom.backward_travel_mode : phantom_node_pair.target_phantom.forward_travel_mode, INVALID_ENTRY_CLASSID, - datasource_vector[i]}); + datasource_vector[segment_idx]}); } if (unpacked_path.size() > 0) diff --git a/include/extractor/compressed_edge_container.hpp b/include/extractor/compressed_edge_container.hpp index a4efc25ba..7e986409f 100644 --- a/include/extractor/compressed_edge_container.hpp +++ b/include/extractor/compressed_edge_container.hpp @@ -16,12 +16,22 @@ namespace extractor class CompressedEdgeContainer { public: - struct CompressedEdge + struct OnewayCompressedEdge { public: NodeID node_id; // refers to an internal node-based-node EdgeWeight weight; // the weight of the edge leading to this node }; + + struct CompressedEdge + { + public: + NodeID node_id; + EdgeWeight forward_weight; + EdgeWeight reverse_weight; + }; + + using OnewayEdgeBucket = std::vector; using EdgeBucket = std::vector; CompressedEdgeContainer(); @@ -35,11 +45,18 @@ class CompressedEdgeContainer void AddUncompressedEdge(const EdgeID edge_id, const NodeID target_node, const EdgeWeight weight); + void InitializeBothwayVector(); + unsigned ZipEdges(const unsigned f_edge_pos, const unsigned r_edge_pos); + bool HasEntryForID(const EdgeID edge_id) const; + bool HasZippedEntryForForwardID(const EdgeID edge_id) const; + bool HasZippedEntryForReverseID(const EdgeID edge_id) const; void PrintStatistics() const; void SerializeInternalVector(const std::string &path) const; unsigned GetPositionForID(const EdgeID edge_id) const; - const EdgeBucket &GetBucketReference(const EdgeID edge_id) const; + unsigned GetZippedPositionForForwardID(const EdgeID edge_id) const; + unsigned GetZippedPositionForReverseID(const EdgeID edge_id) const; + const OnewayEdgeBucket &GetBucketReference(const EdgeID edge_id) const; bool IsTrivial(const EdgeID edge_id) const; NodeID GetFirstEdgeTargetID(const EdgeID edge_id) const; NodeID GetLastEdgeTargetID(const EdgeID edge_id) const; @@ -49,9 +66,12 @@ class CompressedEdgeContainer int free_list_maximum = 0; void IncreaseFreeList(); + std::vector m_compressed_oneway_geometries; std::vector m_compressed_geometries; std::vector m_free_list; std::unordered_map m_edge_id_to_list_index_map; + std::unordered_map m_forward_edge_id_to_zipped_index_map; + std::unordered_map m_reverse_edge_id_to_zipped_index_map; }; } } diff --git a/include/extractor/edge_based_graph_factory.hpp b/include/extractor/edge_based_graph_factory.hpp index 130e07800..a3227d59a 100644 --- a/include/extractor/edge_based_graph_factory.hpp +++ b/include/extractor/edge_based_graph_factory.hpp @@ -84,7 +84,7 @@ class EdgeBasedGraphFactory EdgeBasedGraphFactory &operator=(const EdgeBasedGraphFactory &) = delete; explicit EdgeBasedGraphFactory(std::shared_ptr node_based_graph, - const CompressedEdgeContainer &compressed_edge_container, + CompressedEdgeContainer &compressed_edge_container, const std::unordered_set &barrier_nodes, const std::unordered_set &traffic_lights, std::shared_ptr restriction_map, @@ -149,7 +149,7 @@ class EdgeBasedGraphFactory const std::unordered_set &m_barrier_nodes; const std::unordered_set &m_traffic_lights; - const CompressedEdgeContainer &m_compressed_edge_container; + CompressedEdgeContainer &m_compressed_edge_container; ProfileProperties profile_properties; diff --git a/include/extractor/edge_based_node.hpp b/include/extractor/edge_based_node.hpp index 6ea0349a2..5ad1e1992 100644 --- a/include/extractor/edge_based_node.hpp +++ b/include/extractor/edge_based_node.hpp @@ -22,8 +22,8 @@ struct EdgeBasedNode EdgeBasedNode() : forward_segment_id{SPECIAL_SEGMENTID, false}, reverse_segment_id{SPECIAL_SEGMENTID, false}, u(SPECIAL_NODEID), v(SPECIAL_NODEID), - name_id(0), forward_packed_geometry_id(SPECIAL_EDGEID), - reverse_packed_geometry_id(SPECIAL_EDGEID), component{INVALID_COMPONENTID, false}, + name_id(0), packed_geometry_id(SPECIAL_GEOMETRYID), + component{INVALID_COMPONENTID, false}, fwd_segment_position(std::numeric_limits::max()), forward_travel_mode(TRAVEL_MODE_INACCESSIBLE), backward_travel_mode(TRAVEL_MODE_INACCESSIBLE) @@ -35,16 +35,14 @@ struct EdgeBasedNode NodeID u, NodeID v, unsigned name_id, - unsigned forward_geometry_id_, - unsigned reverse_geometry_id_, + unsigned packed_geometry_id_, bool is_tiny_component, unsigned component_id, unsigned short fwd_segment_position, TravelMode forward_travel_mode, TravelMode backward_travel_mode) : forward_segment_id(forward_segment_id_), reverse_segment_id(reverse_segment_id_), u(u), - v(v), name_id(name_id), forward_packed_geometry_id(forward_geometry_id_), - reverse_packed_geometry_id(reverse_geometry_id_), + v(v), name_id(name_id), packed_geometry_id(packed_geometry_id_), component{component_id, is_tiny_component}, fwd_segment_position(fwd_segment_position), forward_travel_mode(forward_travel_mode), backward_travel_mode(backward_travel_mode) { @@ -57,8 +55,7 @@ struct EdgeBasedNode NodeID v; // indices into the coordinates array unsigned name_id; // id of the edge name - unsigned forward_packed_geometry_id; - unsigned reverse_packed_geometry_id; + unsigned packed_geometry_id; struct { unsigned id : 31; diff --git a/include/extractor/guidance/toolkit.hpp b/include/extractor/guidance/toolkit.hpp index b505590e3..1a87f1162 100644 --- a/include/extractor/guidance/toolkit.hpp +++ b/include/extractor/guidance/toolkit.hpp @@ -125,7 +125,7 @@ getRepresentativeCoordinate(const NodeID from_node, }; // Uncompressed roads are simple, return the coordinate at the end - if (!compressed_geometries.HasEntryForID(via_edge_id)) + if (!compressed_geometries.HasZippedEntryForForwardID(via_edge_id) && !compressed_geometries.HasZippedEntryForReverseID(via_edge_id)) { return extractCoordinateFromNode(traverse_in_reverse ? query_nodes[from_node] : query_nodes[to_node]); diff --git a/include/extractor/original_edge_data.hpp b/include/extractor/original_edge_data.hpp index 558fcb6a0..9a2778aaa 100644 --- a/include/extractor/original_edge_data.hpp +++ b/include/extractor/original_edge_data.hpp @@ -15,26 +15,26 @@ namespace extractor struct OriginalEdgeData { - explicit OriginalEdgeData(NodeID via_node, + explicit OriginalEdgeData(GeometryID via_geometry, unsigned name_id, LaneDataID lane_data_id, guidance::TurnInstruction turn_instruction, EntryClassID entry_classid, TravelMode travel_mode) - : via_node(via_node), name_id(name_id), entry_classid(entry_classid), + : via_geometry(via_geometry), name_id(name_id), entry_classid(entry_classid), lane_data_id(lane_data_id), turn_instruction(turn_instruction), travel_mode(travel_mode) { } OriginalEdgeData() - : via_node(std::numeric_limits::max()), + : via_geometry{std::numeric_limits::max() >> 1, false}, name_id(std::numeric_limits::max()), entry_classid(INVALID_ENTRY_CLASSID), lane_data_id(INVALID_LANE_DATAID), turn_instruction(guidance::TurnInstruction::INVALID()), travel_mode(TRAVEL_MODE_INACCESSIBLE) { } - NodeID via_node; + GeometryID via_geometry; unsigned name_id; EntryClassID entry_classid; LaneDataID lane_data_id; diff --git a/include/util/shared_memory_vector_wrapper.hpp b/include/util/shared_memory_vector_wrapper.hpp index 2fec536be..f4a85dbbc 100644 --- a/include/util/shared_memory_vector_wrapper.hpp +++ b/include/util/shared_memory_vector_wrapper.hpp @@ -46,6 +46,34 @@ template class ShMemIterator : public std::iterator class ShMemReverseIterator : public std::iterator +{ + DataT *p; + + public: + explicit ShMemReverseIterator(DataT *x) : p(x) {} + ShMemReverseIterator(const ShMemReverseIterator &mit) : p(mit.p) {} + ShMemReverseIterator &operator++() + { + --p; + return *this; + } + ShMemReverseIterator operator++(int) + { + ShMemReverseIterator tmp(*this); + operator++(); + return tmp; + } + ShMemReverseIterator operator+(std::ptrdiff_t diff) + { + ShMemReverseIterator tmp(p - diff); + return tmp; + } + bool operator==(const ShMemReverseIterator &rhs) { return p == rhs.p; } + bool operator!=(const ShMemReverseIterator &rhs) { return p != rhs.p; } + DataT &operator*() { return *p; } +}; + template class SharedMemoryWrapper { private: @@ -71,6 +99,10 @@ template class SharedMemoryWrapper ShMemIterator end() const { return ShMemIterator(m_ptr + m_size); } + ShMemReverseIterator rbegin() const { return ShMemReverseIterator(m_ptr + m_size - 1); } + + ShMemReverseIterator rend() const { return ShMemReverseIterator(m_ptr - 1); } + std::size_t size() const { return m_size; } bool empty() const { return 0 == size(); } diff --git a/include/util/typedefs.hpp b/include/util/typedefs.hpp index 36797eea0..b8cb0b4fa 100644 --- a/include/util/typedefs.hpp +++ b/include/util/typedefs.hpp @@ -77,6 +77,7 @@ static const EntryClassID INVALID_ENTRY_CLASSID = std::numeric_limits::max(); static const NodeID SPECIAL_SEGMENTID = std::numeric_limits::max() >> 1; +static const NodeID SPECIAL_GEOMETRYID = std::numeric_limits::max() >> 1; static const EdgeID SPECIAL_EDGEID = std::numeric_limits::max(); static const NameID INVALID_NAMEID = std::numeric_limits::max(); static const NameID EMPTY_NAMEID = 0; @@ -96,6 +97,22 @@ struct SegmentID std::uint32_t enabled : 1; }; +/* We need to bit pack here because the index for the via_node + * is given to us without knowing whether the geometry should + * be read forward or in reverse. The extra field `forward` + * indicates that to the routing engine + */ +struct GeometryID +{ + GeometryID(const NodeID id_, const bool forward_) : id{id_}, forward{forward_} {} + + GeometryID() : id(std::numeric_limits::max() >> 1), forward(false) {} + + NodeID id : 31; + std::uint32_t forward : 1; +}; + + static_assert(sizeof(SegmentID) == 4, "SegmentID needs to be 4 bytes big"); #endif /* TYPEDEFS_H */ diff --git a/src/contractor/contractor.cpp b/src/contractor/contractor.cpp index 2d66845e9..efa114b81 100644 --- a/src/contractor/contractor.cpp +++ b/src/contractor/contractor.cpp @@ -593,106 +593,66 @@ EdgeID Contractor::LoadEdgeExpandedGraph( extractor::QueryNode *u; extractor::QueryNode *v; - // forward_packed_geometry_id is the index id for geometry, weight and duration of - // the segments - if (leaf_object.forward_packed_geometry_id != SPECIAL_EDGEID) + const unsigned forward_begin = + m_geometry_indices.at(leaf_object.packed_geometry_id); + const auto current_segment = + &(m_geometry_list[forward_begin + leaf_object.fwd_segment_position]); + + u = &(internal_to_external_node_map + [m_geometry_list[forward_begin + + leaf_object.fwd_segment_position] + .node_id]); + v = &(internal_to_external_node_map + [m_geometry_list[forward_begin + leaf_object.fwd_segment_position + 1] + .node_id]); + + const double segment_length = util::coordinate_calculation::greatCircleDistance( + util::Coordinate{u->lon, u->lat}, util::Coordinate{v->lon, v->lat}); + + auto forward_speed_iter = + find(segment_speed_lookup, Segment{u->node_id, v->node_id}); + if (forward_speed_iter != segment_speed_lookup.end()) { - const unsigned forward_begin = - m_geometry_indices.at(leaf_object.forward_packed_geometry_id); - const auto current_fwd_segment = - &(m_geometry_list[forward_begin + leaf_object.fwd_segment_position]); + const auto new_segment_weight = getNewWeight(forward_speed_iter, + segment_length, + segment_speed_filenames, + current_segment->forward_weight, + log_edge_updates_factor); - if (leaf_object.fwd_segment_position == 0) - { - u = &(internal_to_external_node_map[leaf_object.u]); - v = &( - internal_to_external_node_map[m_geometry_list[forward_begin].node_id]); - } - else - { - u = &(internal_to_external_node_map - [m_geometry_list[forward_begin + - leaf_object.fwd_segment_position - 1] - .node_id]); - v = &(internal_to_external_node_map[current_fwd_segment->node_id]); - } - const double segment_length = util::coordinate_calculation::greatCircleDistance( - util::Coordinate{u->lon, u->lat}, util::Coordinate{v->lon, v->lat}); + m_geometry_list[forward_begin + 1 + leaf_object.fwd_segment_position].forward_weight = + new_segment_weight; + m_geometry_datasource[forward_begin + 1 + leaf_object.fwd_segment_position] = + forward_speed_iter->speed_source.source; - auto forward_speed_iter = - find(segment_speed_lookup, Segment{u->node_id, v->node_id}); - - if (forward_speed_iter != segment_speed_lookup.end()) - { - const auto new_segment_weight = getNewWeight(forward_speed_iter, - segment_length, - segment_speed_filenames, - current_fwd_segment->weight, - log_edge_updates_factor); - current_fwd_segment->weight = new_segment_weight; - m_geometry_datasource[forward_begin + leaf_object.fwd_segment_position] = - forward_speed_iter->speed_source.source; - - // count statistics for logging - counters[forward_speed_iter->speed_source.source] += 1; - } - else - { - // count statistics for logging - counters[LUA_SOURCE] += 1; - } + // count statistics for logging + counters[forward_speed_iter->speed_source.source] += 1; } - // reverse_packed_geometry_id is the index id for geometry, weight and duration of - // the segment - if (leaf_object.reverse_packed_geometry_id != SPECIAL_EDGEID) + else { - const unsigned reverse_begin = - m_geometry_indices.at(leaf_object.reverse_packed_geometry_id); - const unsigned reverse_end = - m_geometry_indices.at(leaf_object.reverse_packed_geometry_id + 1); + // count statistics for logging + counters[LUA_SOURCE] += 1; + } - int rev_segment_position = - (reverse_end - reverse_begin) - leaf_object.fwd_segment_position - 1; - const auto current_rev_segment = - &(m_geometry_list[reverse_begin + rev_segment_position]); - if (rev_segment_position == 0) - { - u = &(internal_to_external_node_map[leaf_object.v]); - v = &( - internal_to_external_node_map[m_geometry_list[reverse_begin].node_id]); - } - else - { - u = &( - internal_to_external_node_map[m_geometry_list[reverse_begin + - rev_segment_position - 1] - .node_id]); - v = &(internal_to_external_node_map[current_rev_segment->node_id]); - } - const double segment_length = util::coordinate_calculation::greatCircleDistance( - util::Coordinate{u->lon, u->lat}, util::Coordinate{v->lon, v->lat}); + const auto reverse_speed_iter = + find(segment_speed_lookup, Segment{v->node_id, u->node_id}); + if (reverse_speed_iter != segment_speed_lookup.end()) + { + const auto new_segment_weight = getNewWeight(reverse_speed_iter, + segment_length, + segment_speed_filenames, + current_segment->reverse_weight, + log_edge_updates_factor); + m_geometry_list[forward_begin + leaf_object.fwd_segment_position].reverse_weight = + new_segment_weight; + m_geometry_datasource[forward_begin + leaf_object.fwd_segment_position] = + reverse_speed_iter->speed_source.source; - auto reverse_speed_iter = - find(segment_speed_lookup, Segment{u->node_id, v->node_id}); - if (reverse_speed_iter != segment_speed_lookup.end()) - { - const auto new_segment_weight = getNewWeight(reverse_speed_iter, - segment_length, - segment_speed_filenames, - current_rev_segment->weight, - log_edge_updates_factor); - current_rev_segment->weight = new_segment_weight; - m_geometry_datasource[reverse_begin + rev_segment_position] = - reverse_speed_iter->speed_source.source; - - // count statistics for logging - counters[reverse_speed_iter->speed_source.source] += 1; - } - else - { - // count statistics for logging - counters[LUA_SOURCE] += 1; - } + // count statistics for logging + counters[reverse_speed_iter->speed_source.source] += 1; + } + else + { + counters[LUA_SOURCE] += 1; } } }); // parallel_for_each @@ -824,7 +784,7 @@ EdgeID Contractor::LoadEdgeExpandedGraph( { if (speed_iter->speed_source.speed > 0) { - auto new_segment_weight = distanceAndSpeedToWeight( + const auto new_segment_weight = distanceAndSpeedToWeight( segmentblocks[i].segment_length, speed_iter->speed_source.speed); new_weight += new_segment_weight; } diff --git a/src/engine/plugins/tile.cpp b/src/engine/plugins/tile.cpp index 9aba6ce4a..dc9f06e88 100644 --- a/src/engine/plugins/tile.cpp +++ b/src/engine/plugins/tile.cpp @@ -427,7 +427,7 @@ Status TilePlugin::HandleRequest(const std::shared_ptrGetUncompressedGeometry(source_ebn.second.packed_geometry_id, first_geometry); + first_geometry = facade->GetUncompressedForwardGeometry(source_ebn.second.packed_geometry_id); // We earlier saved the source and target intersection nodes for every road section. // We can use the target node to find all road sections that lead away from @@ -532,14 +531,11 @@ Status TilePlugin::HandleRequest(const std::shared_ptrGetUncompressedGeometry( - edge_based_node_info.at(target_ebn).packed_geometry_id, second_geometry); + second_geometry = facade->GetUncompressedReverseGeometry( + edge_based_node_info.at(target_ebn).packed_geometry_id); // Now, calculate the sum of the weight of all the segments. - forward_weight_vector.clear(); - facade->GetUncompressedWeights(source_ebn.second.packed_geometry_id, - forward_weight_vector); + forward_weight_vector = facade->GetUncompressedForwardWeights(source_ebn.second.packed_geometry_id); const auto sum_node_weight = std::accumulate( forward_weight_vector.begin(), forward_weight_vector.end(), EdgeWeight{0}); @@ -616,38 +612,30 @@ Status TilePlugin::HandleRequest(const std::shared_ptrGetUncompressedWeights(edge.forward_packed_geometry_id, forward_weight_vector); - forward_weight = forward_weight_vector[edge.fwd_segment_position]; + forward_weight_vector = + facade->GetUncompressedForwardWeights(edge.packed_geometry_id); + reverse_weight_vector = + facade->GetUncompressedReverseWeights(edge.packed_geometry_id); - forward_datasource_vector.clear(); - facade->GetUncompressedDatasources(edge.forward_packed_geometry_id, - forward_datasource_vector); - forward_datasource = forward_datasource_vector[edge.fwd_segment_position]; + forward_weight = forward_weight_vector[edge.fwd_segment_position]; - use_line_value(forward_weight); - } + BOOST_ASSERT(edge.fwd_segment_position < reverse_weight_vector.size()); + reverse_weight = + reverse_weight_vector[reverse_weight_vector.size() - edge.fwd_segment_position - 1]; - if (edge.reverse_packed_geometry_id != SPECIAL_EDGEID) - { - reverse_weight_vector.clear(); - facade->GetUncompressedWeights(edge.reverse_packed_geometry_id, reverse_weight_vector); + forward_datasource_vector.clear(); + forward_datasource_vector = facade->GetUncompressedForwardDatasources(edge.packed_geometry_id); + forward_datasource = forward_datasource_vector[edge.fwd_segment_position]; - BOOST_ASSERT(edge.fwd_segment_position < reverse_weight_vector.size()); + reverse_datasource_vector.clear(); + // TODO have not tested geom zipping with tiles yet + reverse_datasource_vector = + facade->GetUncompressedReverseDatasources(edge.packed_geometry_id); + reverse_datasource = reverse_datasource_vector[reverse_datasource_vector.size() - + edge.fwd_segment_position - 1]; - reverse_weight = - reverse_weight_vector[reverse_weight_vector.size() - edge.fwd_segment_position - 1]; + use_line_value(reverse_weight); - reverse_datasource_vector.clear(); - facade->GetUncompressedDatasources(edge.reverse_packed_geometry_id, - reverse_datasource_vector); - reverse_datasource = reverse_datasource_vector[reverse_datasource_vector.size() - - edge.fwd_segment_position - 1]; - - use_line_value(reverse_weight); - } // Keep track of the highest datasource seen so that we don't write unnecessary // data to the layer attribute values max_datasource_id = std::max(max_datasource_id, forward_datasource); @@ -704,40 +692,37 @@ Status TilePlugin::HandleRequest(const std::shared_ptrGetUncompressedForwardWeights(edge.packed_geometry_id); + forward_weight = forward_weight_vector[edge.fwd_segment_position]; + + forward_datasource_vector.clear(); + forward_datasource_vector = + facade->GetUncompressedForwardDatasources(edge.packed_geometry_id); + forward_datasource = forward_datasource_vector[edge.fwd_segment_position]; + + reverse_weight_vector.clear(); + reverse_weight_vector = + facade->GetUncompressedReverseWeights(edge.packed_geometry_id); std::string name = facade->GetNameForID(edge.name_id); - if (edge.forward_packed_geometry_id != SPECIAL_EDGEID) - { - forward_weight_vector.clear(); - facade->GetUncompressedWeights(edge.forward_packed_geometry_id, - forward_weight_vector); - forward_weight = forward_weight_vector[edge.fwd_segment_position]; + forward_weight_vector = facade->GetUncompressedForwardWeights(edge.packed_geometry_id); + forward_weight = forward_weight_vector[edge.fwd_segment_position]; - forward_datasource_vector.clear(); - facade->GetUncompressedDatasources(edge.forward_packed_geometry_id, - forward_datasource_vector); - forward_datasource = forward_datasource_vector[edge.fwd_segment_position]; - } + forward_datasource_vector = facade->GetUncompressedForwardDatasources(edge.packed_geometry_id); + forward_datasource = forward_datasource_vector[edge.fwd_segment_position]; - if (edge.reverse_packed_geometry_id != SPECIAL_EDGEID) - { - reverse_weight_vector.clear(); - facade->GetUncompressedWeights(edge.reverse_packed_geometry_id, - reverse_weight_vector); + reverse_weight_vector = facade->GetUncompressedReverseWeights(edge.packed_geometry_id); - BOOST_ASSERT(edge.fwd_segment_position < reverse_weight_vector.size()); + reverse_weight = reverse_weight_vector[reverse_weight_vector.size() - + edge.fwd_segment_position - 1]; - reverse_weight = reverse_weight_vector[reverse_weight_vector.size() - - edge.fwd_segment_position - 1]; - - reverse_datasource_vector.clear(); - facade->GetUncompressedDatasources(edge.reverse_packed_geometry_id, - reverse_datasource_vector); - reverse_datasource = - reverse_datasource_vector[reverse_datasource_vector.size() - - edge.fwd_segment_position - 1]; - } + reverse_datasource_vector = facade->GetUncompressedReverseDatasources(edge.packed_geometry_id); + reverse_datasource = + reverse_datasource_vector[reverse_datasource_vector.size() - + edge.fwd_segment_position - 1]; // Keep track of the highest datasource seen so that we don't write unnecessary // data to the layer attribute values @@ -848,6 +833,12 @@ Status TilePlugin::HandleRequest(const std::shared_ptrGetUncompressedReverseDatasources(edge.packed_geometry_id); + reverse_datasource = + reverse_datasource_vector[reverse_datasource_vector.size() - + edge.fwd_segment_position - 1]; } } diff --git a/src/extractor/compressed_edge_container.cpp b/src/extractor/compressed_edge_container.cpp index c0529ad00..0fd7f30ce 100644 --- a/src/extractor/compressed_edge_container.cpp +++ b/src/extractor/compressed_edge_container.cpp @@ -23,7 +23,7 @@ CompressedEdgeContainer::CompressedEdgeContainer() void CompressedEdgeContainer::IncreaseFreeList() { - m_compressed_geometries.resize(m_compressed_geometries.size() + 100); + m_compressed_oneway_geometries.resize(m_compressed_oneway_geometries.size() + 100); for (unsigned i = 100; i > 0; --i) { m_free_list.emplace_back(free_list_maximum); @@ -37,17 +37,44 @@ bool CompressedEdgeContainer::HasEntryForID(const EdgeID edge_id) const return iter != m_edge_id_to_list_index_map.end(); } +bool CompressedEdgeContainer::HasZippedEntryForForwardID(const EdgeID edge_id) const +{ + auto iter = m_forward_edge_id_to_zipped_index_map.find(edge_id); + return iter != m_forward_edge_id_to_zipped_index_map.end(); +} + +bool CompressedEdgeContainer::HasZippedEntryForReverseID(const EdgeID edge_id) const +{ + auto iter = m_reverse_edge_id_to_zipped_index_map.find(edge_id); + return iter != m_reverse_edge_id_to_zipped_index_map.end(); +} + unsigned CompressedEdgeContainer::GetPositionForID(const EdgeID edge_id) const { auto map_iterator = m_edge_id_to_list_index_map.find(edge_id); BOOST_ASSERT(map_iterator != m_edge_id_to_list_index_map.end()); + BOOST_ASSERT(map_iterator->second < m_compressed_oneway_geometries.size()); + return map_iterator->second; +} + +unsigned CompressedEdgeContainer::GetZippedPositionForForwardID(const EdgeID edge_id) const +{ + auto map_iterator = m_forward_edge_id_to_zipped_index_map.find(edge_id); + BOOST_ASSERT(map_iterator != m_forward_edge_id_to_zipped_index_map.end()); + BOOST_ASSERT(map_iterator->second < m_compressed_geometries.size()); + return map_iterator->second; +} + +unsigned CompressedEdgeContainer::GetZippedPositionForReverseID(const EdgeID edge_id) const +{ + auto map_iterator = m_reverse_edge_id_to_zipped_index_map.find(edge_id); + BOOST_ASSERT(map_iterator != m_reverse_edge_id_to_zipped_index_map.end()); BOOST_ASSERT(map_iterator->second < m_compressed_geometries.size()); return map_iterator->second; } void CompressedEdgeContainer::SerializeInternalVector(const std::string &path) const { - boost::filesystem::fstream geometry_out_stream(path, std::ios::binary | std::ios::out); const unsigned compressed_geometries = m_compressed_geometries.size() + 1; BOOST_ASSERT(std::numeric_limits::max() != compressed_geometries); @@ -135,15 +162,15 @@ void CompressedEdgeContainer::CompressEdge(const EdgeID edge_id_1, BOOST_ASSERT(iter != m_edge_id_to_list_index_map.end()); const unsigned edge_bucket_id1 = iter->second; BOOST_ASSERT(edge_bucket_id1 == GetPositionForID(edge_id_1)); - BOOST_ASSERT(edge_bucket_id1 < m_compressed_geometries.size()); + BOOST_ASSERT(edge_bucket_id1 < m_compressed_oneway_geometries.size()); - std::vector &edge_bucket_list1 = m_compressed_geometries[edge_bucket_id1]; + std::vector &edge_bucket_list1 = m_compressed_oneway_geometries[edge_bucket_id1]; // note we don't save the start coordinate: it is implicitly given by edge 1 // weight1 is the distance to the (currently) last coordinate in the bucket if (edge_bucket_list1.empty()) { - edge_bucket_list1.emplace_back(CompressedEdge{via_node_id, weight1}); + edge_bucket_list1.emplace_back(OnewayCompressedEdge{via_node_id, weight1}); } BOOST_ASSERT(0 < edge_bucket_list1.size()); @@ -153,10 +180,10 @@ void CompressedEdgeContainer::CompressEdge(const EdgeID edge_id_1, { // second edge is not atomic anymore const unsigned list_to_remove_index = GetPositionForID(edge_id_2); - BOOST_ASSERT(list_to_remove_index < m_compressed_geometries.size()); + BOOST_ASSERT(list_to_remove_index < m_compressed_oneway_geometries.size()); - std::vector &edge_bucket_list2 = - m_compressed_geometries[list_to_remove_index]; + std::vector &edge_bucket_list2 = + m_compressed_oneway_geometries[list_to_remove_index]; // found an existing list, append it to the list of edge_id_1 edge_bucket_list1.insert( @@ -174,7 +201,7 @@ void CompressedEdgeContainer::CompressEdge(const EdgeID edge_id_1, else { // we are certain that the second edge is atomic. - edge_bucket_list1.emplace_back(CompressedEdge{target_node_id, weight2}); + edge_bucket_list1.emplace_back(OnewayCompressedEdge{target_node_id, weight2}); } } @@ -206,28 +233,65 @@ void CompressedEdgeContainer::AddUncompressedEdge(const EdgeID edge_id, BOOST_ASSERT(iter != m_edge_id_to_list_index_map.end()); const unsigned edge_bucket_id = iter->second; BOOST_ASSERT(edge_bucket_id == GetPositionForID(edge_id)); - BOOST_ASSERT(edge_bucket_id < m_compressed_geometries.size()); + BOOST_ASSERT(edge_bucket_id < m_compressed_oneway_geometries.size()); - std::vector &edge_bucket_list = m_compressed_geometries[edge_bucket_id]; + std::vector &edge_bucket_list = m_compressed_oneway_geometries[edge_bucket_id]; // note we don't save the start coordinate: it is implicitly given by edge_id // weight is the distance to the (currently) last coordinate in the bucket // Don't re-add this if it's already in there. if (edge_bucket_list.empty()) { - edge_bucket_list.emplace_back(CompressedEdge{target_node_id, weight}); + edge_bucket_list.emplace_back(OnewayCompressedEdge{target_node_id, weight}); } } +void CompressedEdgeContainer::InitializeBothwayVector() +{ + m_compressed_geometries.reserve(m_compressed_oneway_geometries.size() / 2); +} + +unsigned CompressedEdgeContainer::ZipEdges(const EdgeID f_edge_id, const EdgeID r_edge_id) +{ + const auto &forward_bucket = GetBucketReference(f_edge_id); + const auto &reverse_bucket = GetBucketReference(r_edge_id); + + BOOST_ASSERT(forward_bucket.size() == reverse_bucket.size()); + + const unsigned zipped_geometry_id = m_compressed_geometries.size(); + m_forward_edge_id_to_zipped_index_map[f_edge_id] = zipped_geometry_id; + m_reverse_edge_id_to_zipped_index_map[r_edge_id] = zipped_geometry_id; + + std::vector zipped_edge_bucket; + const auto &first_node = reverse_bucket.back(); + zipped_edge_bucket.emplace_back(CompressedEdge{first_node.node_id, INVALID_EDGE_WEIGHT, first_node.weight}); + + for (std::size_t i = 0; i < forward_bucket.size() - 1; ++i) + { + const auto &fwd_node = forward_bucket.at(i); + const auto &rev_node = reverse_bucket.at(reverse_bucket.size() - 2 - i); + + BOOST_ASSERT(fwd_node.node_id == rev_node.node_id); + + zipped_edge_bucket.emplace_back(CompressedEdge{fwd_node.node_id, fwd_node.weight, rev_node.weight}); + } + + const auto &last_node = forward_bucket.back(); + zipped_edge_bucket.emplace_back(CompressedEdge{last_node.node_id, last_node.weight, INVALID_EDGE_WEIGHT}); + m_compressed_geometries.emplace_back(std::move(zipped_edge_bucket)); + + return zipped_geometry_id; +} + void CompressedEdgeContainer::PrintStatistics() const { - const uint64_t compressed_edges = m_compressed_geometries.size(); + const uint64_t compressed_edges = m_compressed_oneway_geometries.size(); BOOST_ASSERT(0 == compressed_edges % 2); - BOOST_ASSERT(m_compressed_geometries.size() + m_free_list.size() > 0); + BOOST_ASSERT(m_compressed_oneway_geometries.size() + m_free_list.size() > 0); uint64_t compressed_geometries = 0; uint64_t longest_chain_length = 0; - for (const std::vector ¤t_vector : m_compressed_geometries) + for (const std::vector ¤t_vector : m_compressed_oneway_geometries) { compressed_geometries += current_vector.size(); longest_chain_length = std::max(longest_chain_length, (uint64_t)current_vector.size()); @@ -243,11 +307,11 @@ void CompressedEdgeContainer::PrintStatistics() const << (float)compressed_geometries / std::max((uint64_t)1, compressed_edges); } -const CompressedEdgeContainer::EdgeBucket & +const CompressedEdgeContainer::OnewayEdgeBucket & CompressedEdgeContainer::GetBucketReference(const EdgeID edge_id) const { const unsigned index = m_edge_id_to_list_index_map.at(edge_id); - return m_compressed_geometries.at(index); + return m_compressed_oneway_geometries.at(index); } // Since all edges are technically in the compressed geometry container, diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index a6fa6c64e..c46f66c85 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -34,7 +34,7 @@ namespace extractor EdgeBasedGraphFactory::EdgeBasedGraphFactory( std::shared_ptr node_based_graph, - const CompressedEdgeContainer &compressed_edge_container, + CompressedEdgeContainer &compressed_edge_container, const std::unordered_set &barrier_nodes, const std::unordered_set &traffic_lights, std::shared_ptr restriction_map, @@ -124,10 +124,12 @@ void EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeI const auto &forward_geometry = m_compressed_edge_container.GetBucketReference(edge_id_1); BOOST_ASSERT(forward_geometry.size() == m_compressed_edge_container.GetBucketReference(edge_id_2).size()); - const auto geometry_size = forward_geometry.size(); + const auto segment_count = forward_geometry.size(); // There should always be some geometry - BOOST_ASSERT(0 != geometry_size); + BOOST_ASSERT(0 != segment_count); + + const unsigned packed_geometry_id = m_compressed_edge_container.ZipEdges(edge_id_1, edge_id_2); NodeID current_edge_source_coordinate_id = node_u; @@ -140,12 +142,12 @@ void EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeI return SegmentID{edge_based_node_id, true}; }; - // traverse arrays from start and end respectively - for (const auto i : util::irange(std::size_t{0}, geometry_size)) + // traverse arrays + for (const auto i : util::irange(std::size_t{0}, segment_count)) { BOOST_ASSERT( current_edge_source_coordinate_id == - m_compressed_edge_container.GetBucketReference(edge_id_2)[geometry_size - 1 - i] + m_compressed_edge_container.GetBucketReference(edge_id_2)[segment_count - 1 - i] .node_id); const NodeID current_edge_target_coordinate_id = forward_geometry[i].node_id; BOOST_ASSERT(current_edge_target_coordinate_id != current_edge_source_coordinate_id); @@ -156,8 +158,7 @@ void EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeI current_edge_source_coordinate_id, current_edge_target_coordinate_id, forward_data.name_id, - m_compressed_edge_container.GetPositionForID(edge_id_1), - m_compressed_edge_container.GetPositionForID(edge_id_2), + packed_geometry_id, false, INVALID_COMPONENTID, i, @@ -257,6 +258,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes() { util::Percent progress(m_node_based_graph->GetNumberOfNodes()); + m_compressed_edge_container.InitializeBothwayVector(); + // loop over all edges and generate new set of nodes for (const auto node_u : util::irange(0u, m_node_based_graph->GetNumberOfNodes())) { @@ -442,14 +445,26 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( distance += turn_penalty; - BOOST_ASSERT(m_compressed_edge_container.HasEntryForID(edge_from_u)); - original_edge_data_vector.emplace_back( - m_compressed_edge_container.GetPositionForID(edge_from_u), - edge_data1.name_id, - turn.lane_data_id, - turn_instruction, - entry_class_id, - edge_data1.travel_mode); + const bool is_encoded_forwards = m_compressed_edge_container.HasZippedEntryForForwardID(edge_from_u); + const bool is_encoded_backwards = m_compressed_edge_container.HasZippedEntryForReverseID(edge_from_u); + BOOST_ASSERT(is_encoded_forwards || is_encoded_backwards); + if (is_encoded_forwards) { + original_edge_data_vector.emplace_back( + GeometryID{m_compressed_edge_container.GetZippedPositionForForwardID(edge_from_u), true}, + edge_data1.name_id, + turn.lane_data_id, + turn_instruction, + entry_class_id, + edge_data1.travel_mode); + } else if (is_encoded_backwards) { + original_edge_data_vector.emplace_back( + GeometryID{m_compressed_edge_container.GetZippedPositionForReverseID(edge_from_u), false}, + edge_data1.name_id, + turn.lane_data_id, + turn_instruction, + entry_class_id, + edge_data1.travel_mode); + } ++original_edges_counter; diff --git a/src/extractor/extractor.cpp b/src/extractor/extractor.cpp index 39af53615..add3f4c7d 100644 --- a/src/extractor/extractor.cpp +++ b/src/extractor/extractor.cpp @@ -474,8 +474,6 @@ Extractor::BuildEdgeExpandedGraph(ScriptingEnvironment &scripting_environment, *node_based_graph, compressed_edge_container); - compressed_edge_container.SerializeInternalVector(config.geometry_output_path); - util::NameTable name_table(config.names_file_name); // could use some additional capacity? To avoid a copy during processing, though small data so @@ -505,6 +503,7 @@ Extractor::BuildEdgeExpandedGraph(ScriptingEnvironment &scripting_environment, config.generate_edge_lookup); WriteTurnLaneData(config.turn_lane_descriptions_file_name); + compressed_edge_container.SerializeInternalVector(config.geometry_output_path); edge_based_graph_factory.GetEdgeBasedEdges(edge_based_edge_list); edge_based_graph_factory.GetEdgeBasedNodes(node_based_edge_list); diff --git a/src/storage/storage.cpp b/src/storage/storage.cpp index c89ee631d..f42c64fcf 100644 --- a/src/storage/storage.cpp +++ b/src/storage/storage.cpp @@ -497,7 +497,7 @@ int Storage::Run() } // load original edge information - NodeID *via_node_ptr = shared_layout_ptr->GetBlockPtr( + GeometryID *via_geometry_ptr = shared_layout_ptr->GetBlockPtr( shared_memory_ptr, SharedDataLayout::VIA_NODE_LIST); unsigned *name_id_ptr = shared_layout_ptr->GetBlockPtr( @@ -521,7 +521,7 @@ int Storage::Run() for (unsigned i = 0; i < number_of_original_edges; ++i) { edges_input_stream.read((char *)&(current_edge_data), sizeof(extractor::OriginalEdgeData)); - via_node_ptr[i] = current_edge_data.via_node; + via_geometry_ptr[i] = current_edge_data.via_geometry; name_id_ptr[i] = current_edge_data.name_id; travel_mode_ptr[i] = current_edge_data.travel_mode; lane_data_id_ptr[i] = current_edge_data.lane_data_id; diff --git a/unit_tests/mocks/mock_datafacade.hpp b/unit_tests/mocks/mock_datafacade.hpp index 82ec691dd..6e5b8741a 100644 --- a/unit_tests/mocks/mock_datafacade.hpp +++ b/unit_tests/mocks/mock_datafacade.hpp @@ -61,23 +61,39 @@ class MockDataFacade final : public engine::datafacade::BaseDataFacade } OSMNodeID GetOSMNodeIDOfNode(const unsigned /* id */) const override { return OSMNodeID{0}; } bool EdgeIsCompressed(const unsigned /* id */) const { return false; } - unsigned GetGeometryIndexForEdgeID(const unsigned /* id */) const override + GeometryID GetGeometryIndexForEdgeID(const unsigned /* id */) const override { - return SPECIAL_NODEID; + return GeometryID{SPECIAL_GEOMETRYID, false}; } - void GetUncompressedGeometry(const EdgeID /* id */, - std::vector & /* result_nodes */) const override + std::vector GetUncompressedForwardGeometry(const EdgeID /* id */) const override { + return {}; } - void GetUncompressedWeights(const EdgeID /* id */, - std::vector &result_weights) const override + std::vector GetUncompressedReverseGeometry(const EdgeID /* id */) const override { + return {}; + } + std::vector GetUncompressedForwardWeights(const EdgeID /* id */) const override + { + std::vector result_weights; result_weights.resize(1); result_weights[0] = 1; + return result_weights; } - void GetUncompressedDatasources(const EdgeID /*id*/, - std::vector & /*data_sources*/) const override + std::vector GetUncompressedReverseWeights(const EdgeID /* id */) const override { + std::vector result_weights; + result_weights.resize(1); + result_weights[0] = 1; + return result_weights; + } + std::vector GetUncompressedForwardDatasources(const EdgeID /*id*/) const override + { + return {}; + } + std::vector GetUncompressedReverseDatasources(const EdgeID /*id*/) const override + { + return {}; } std::string GetDatasourceName(const uint8_t /*datasource_name_id*/) const override { diff --git a/unit_tests/server/parameters_parser.cpp b/unit_tests/server/parameters_parser.cpp index 101fd2bfb..193abb5b8 100644 --- a/unit_tests/server/parameters_parser.cpp +++ b/unit_tests/server/parameters_parser.cpp @@ -74,6 +74,15 @@ BOOST_AUTO_TEST_CASE(invalid_table_urls) BOOST_CHECK_EQUAL(testInvalidOptions("1,2;3,4?destinations=foo"), 21UL); } +BOOST_AUTO_TEST_CASE(valid_route_hint) +{ + auto hint = engine::Hint::FromBase64( + "XAYAgP___3-QAAAABAAAACEAAAA_AAAAHgAAAHsFAAAUAAAAaWhxALeCmwI7aHEAy4KbAgUAAQE0h8Z2"); + BOOST_CHECK_EQUAL( + hint.phantom.input_location, + util::Coordinate(util::FloatLongitude{7.432251}, util::FloatLatitude{43.745995})); +} + BOOST_AUTO_TEST_CASE(valid_route_urls) { std::vector coords_1 = {{util::FloatLongitude{1}, util::FloatLatitude{2}}, @@ -137,15 +146,12 @@ BOOST_AUTO_TEST_CASE(valid_route_urls) CHECK_EQUAL_RANGE(reference_3.hints, result_3->hints); std::vector> hints_4 = { - engine::Hint::FromBase64("DAIAgP___" - "38AAAAAAAAAAAIAAAAAAAAAEAAAAOgDAAD0AwAAGwAAAOUacQBQP5sCshpxAB0_" - "mwIAAAEBl-Umfg=="), - engine::Hint::FromBase64("cgAAgP___" - "39jAAAADgAAACIAAABeAAAAkQAAANoDAABOAgAAGwAAAFVGcQCiRJsCR0VxAOZFmw" - "IFAAEBl-Umfg=="), - engine::Hint::FromBase64("3gAAgP___" - "39KAAAAHgAAACEAAAAAAAAAGAAAAE0BAABOAQAAGwAAAIAzcQBkUJsC1zNxAHBQmw" - "IAAAEBl-Umfg==")}; + engine::Hint::FromBase64( + "XAYAgP___3-QAAAABAAAACEAAAA_AAAAHgAAAHsFAAAUAAAAaWhxALeCmwI7aHEAy4KbAgUAAQE0h8Z2"), + engine::Hint::FromBase64( + "lgQAgP___3-QAAAADwAAABMAAAAoAAAALAAAADQAAAAUAAAAmWFxAL1zmwLcYXEAu3ObAgQAAQE0h8Z2"), + engine::Hint::FromBase64( + "OAUAgMUFAIAAAAAADwAAAAIAAAAAAAAAnQAAALwEAAAUAAAAgz5xAE9WmwKIPnEAUFabAgAAAQE0h8Z2")}; RouteParameters reference_4{false, false, false, @@ -158,9 +164,9 @@ BOOST_AUTO_TEST_CASE(valid_route_urls) std::vector>{}}; auto result_4 = parseParameters( "1,2;3,4?steps=false&hints=" - "DAIAgP___38AAAAAAAAAAAIAAAAAAAAAEAAAAOgDAAD0AwAAGwAAAOUacQBQP5sCshpxAB0_mwIAAAEBl-Umfg==;" - "cgAAgP___39jAAAADgAAACIAAABeAAAAkQAAANoDAABOAgAAGwAAAFVGcQCiRJsCR0VxAOZFmwIFAAEBl-Umfg==;" - "3gAAgP___39KAAAAHgAAACEAAAAAAAAAGAAAAE0BAABOAQAAGwAAAIAzcQBkUJsC1zNxAHBQmwIAAAEBl-Umfg=="); + "XAYAgP___3-QAAAABAAAACEAAAA_AAAAHgAAAHsFAAAUAAAAaWhxALeCmwI7aHEAy4KbAgUAAQE0h8Z2;" + "lgQAgP___3-QAAAADwAAABMAAAAoAAAALAAAADQAAAAUAAAAmWFxAL1zmwLcYXEAu3ObAgQAAQE0h8Z2;" + "OAUAgMUFAIAAAAAADwAAAAIAAAAAAAAAnQAAALwEAAAUAAAAgz5xAE9WmwKIPnEAUFabAgAAAQE0h8Z2"); BOOST_CHECK(result_4); BOOST_CHECK_EQUAL(reference_4.steps, result_4->steps); BOOST_CHECK_EQUAL(reference_4.alternatives, result_4->alternatives); @@ -255,13 +261,11 @@ BOOST_AUTO_TEST_CASE(valid_route_urls) {util::FloatLongitude{5}, util::FloatLatitude{6}}, {util::FloatLongitude{7}, util::FloatLatitude{8}}}; std::vector> hints_10 = { - engine::Hint::FromBase64("DAIAgP___" - "38AAAAAAAAAAAIAAAAAAAAAEAAAAOgDAAD0AwAAGwAAAOUacQBQP5sCshpxAB0_" - "mwIAAAEBl-Umfg=="), + engine::Hint::FromBase64( + "XAYAgP___3-QAAAABAAAACEAAAA_AAAAHgAAAHsFAAAUAAAAaWhxALeCmwI7aHEAy4KbAgUAAQE0h8Z2"), boost::none, - engine::Hint::FromBase64("cgAAgP___" - "39jAAAADgAAACIAAABeAAAAkQAAANoDAABOAgAAGwAAAFVGcQCiRJsCR0VxAOZFmw" - "IFAAEBl-Umfg=="), + engine::Hint::FromBase64( + "lgQAgP___3-QAAAADwAAABMAAAAoAAAALAAAADQAAAAUAAAAmWFxAL1zmwLcYXEAu3ObAgQAAQE0h8Z2"), boost::none}; RouteParameters reference_10{false, false, @@ -275,8 +279,8 @@ BOOST_AUTO_TEST_CASE(valid_route_urls) std::vector>{}}; auto result_10 = parseParameters( "1,2;3,4;5,6;7,8?steps=false&hints=" - "DAIAgP___38AAAAAAAAAAAIAAAAAAAAAEAAAAOgDAAD0AwAAGwAAAOUacQBQP5sCshpxAB0_mwIAAAEBl-Umfg==;;" - "cgAAgP___39jAAAADgAAACIAAABeAAAAkQAAANoDAABOAgAAGwAAAFVGcQCiRJsCR0VxAOZFmwIFAAEBl-Umfg==" + "XAYAgP___3-QAAAABAAAACEAAAA_AAAAHgAAAHsFAAAUAAAAaWhxALeCmwI7aHEAy4KbAgUAAQE0h8Z2;;" + "lgQAgP___3-QAAAADwAAABMAAAAoAAAALAAAADQAAAAUAAAAmWFxAL1zmwLcYXEAu3ObAgQAAQE0h8Z2" ";"); BOOST_CHECK(result_10); BOOST_CHECK_EQUAL(reference_10.steps, result_10->steps); diff --git a/unit_tests/util/static_rtree.cpp b/unit_tests/util/static_rtree.cpp index 702449283..3b5de011c 100644 --- a/unit_tests/util/static_rtree.cpp +++ b/unit_tests/util/static_rtree.cpp @@ -166,8 +166,7 @@ struct GraphFixture d.forward_segment_id = {pair.second, true}; d.reverse_segment_id = {pair.first, true}; d.fwd_segment_position = 0; - d.forward_packed_geometry_id = 0; - d.reverse_packed_geometry_id = 0; + d.packed_geometry_id = 0; edges.emplace_back(d); } }