diff --git a/include/engine/datafacade/contiguous_internalmem_datafacade.hpp b/include/engine/datafacade/contiguous_internalmem_datafacade.hpp index 0f53bfb93..3bc2ce660 100644 --- a/include/engine/datafacade/contiguous_internalmem_datafacade.hpp +++ b/include/engine/datafacade/contiguous_internalmem_datafacade.hpp @@ -16,10 +16,12 @@ #include "engine/algorithm.hpp" #include "engine/geospatial_query.hpp" +#include "util/cell_storage.hpp" #include "util/exception.hpp" #include "util/exception_utils.hpp" #include "util/guidance/turn_bearing.hpp" #include "util/log.hpp" +#include "util/multi_level_partition.hpp" #include "util/name_table.hpp" #include "util/packed_vector.hpp" #include "util/range_table.hpp" @@ -249,6 +251,10 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade std::shared_ptr> m_bearing_ranges_table; util::ShM::vector m_bearing_values_table; + // MLD data + util::PackedMultiLevelPartition mld_partition; + util::CellStorage mld_cell_storage; + // allocator that keeps the allocation data std::shared_ptr allocator; @@ -534,6 +540,27 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade m_entry_class_table = std::move(entry_class_table); } + void InitializeMLDDataPointers(storage::DataLayout &data_layout, char *memory_block) + { + if (data_layout.GetBlockSize(storage::DataLayout::MLD_CELL_PARTITION) > 0) + { + auto mld_partition_ptr = + data_layout.GetBlockPtr(memory_block, storage::DataLayout::MLD_CELL_PARTITION); + mld_partition.InitializePointers( + mld_partition_ptr, + mld_partition_ptr + data_layout.num_entries[storage::DataLayout::MLD_CELL_PARTITION]); + } + + if (data_layout.GetBlockSize(storage::DataLayout::MLD_CELL_STORAGE) > 0) + { + auto mld_cell_storage_ptr = + data_layout.GetBlockPtr(memory_block, storage::DataLayout::MLD_CELL_STORAGE); + mld_cell_storage.InitializePointers( + mld_cell_storage_ptr, + mld_cell_storage_ptr + data_layout.num_entries[storage::DataLayout::MLD_CELL_STORAGE]); + } + } + void InitializeInternalPointers(storage::DataLayout &data_layout, char *memory_block) { InitializeChecksumPointer(data_layout, memory_block); @@ -547,6 +574,7 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade InitializeProfilePropertiesPointer(data_layout, memory_block); InitializeRTreePointers(data_layout, memory_block); InitializeIntersectionClassPointers(data_layout, memory_block); + InitializeMLDDataPointers(data_layout, memory_block); } public: @@ -1049,6 +1077,13 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade m_lane_description_masks.begin() + m_lane_description_offsets[lane_description_id + 1]); } + + const util::PackedMultiLevelPartition &GetMultiLevelPartition() const + { + return mld_partition; + } + + const util::CellStorage &GetCellStorage() const { return mld_cell_storage; } }; template class ContiguousInternalMemoryDataFacade; diff --git a/include/partition/partition_config.hpp b/include/partition/partition_config.hpp index c4b2d2031..81679168b 100644 --- a/include/partition/partition_config.hpp +++ b/include/partition/partition_config.hpp @@ -13,7 +13,10 @@ namespace partition struct PartitionConfig { - PartitionConfig() : requested_num_threads(0) {} + PartitionConfig() + : requested_num_threads(0) + { + } void UseDefaults() { @@ -34,6 +37,8 @@ struct PartitionConfig compressed_node_based_graph_path = basepath + ".osrm.cnbg"; cnbg_ebg_mapping_path = basepath + ".osrm.cnbg_to_ebg"; partition_path = basepath + ".osrm.partition"; + mld_partition_path = basepath + ".osrm.mld_partition"; + mld_storage_path = basepath + ".osrm.mld_storage"; } // might be changed to the node based graph at some point @@ -42,6 +47,8 @@ struct PartitionConfig boost::filesystem::path compressed_node_based_graph_path; boost::filesystem::path cnbg_ebg_mapping_path; boost::filesystem::path partition_path; + boost::filesystem::path mld_partition_path; + boost::filesystem::path mld_storage_path; unsigned requested_num_threads; diff --git a/include/partition/recursive_bisection.hpp b/include/partition/recursive_bisection.hpp index 4a6174f2c..4c42e3c0d 100644 --- a/include/partition/recursive_bisection.hpp +++ b/include/partition/recursive_bisection.hpp @@ -26,6 +26,8 @@ class RecursiveBisection const std::vector &BisectionIDs() const; + std::uint32_t SCCDepth() const; + private: BisectionGraph &bisection_graph; RecursiveBisectionState internal_state; diff --git a/include/storage/io.hpp b/include/storage/io.hpp index 497b41aa1..220639752 100644 --- a/include/storage/io.hpp +++ b/include/storage/io.hpp @@ -134,6 +134,26 @@ class FileReader ReadInto(data.data(), count); } + template std::size_t GetVectorMemorySize() + { + const auto count = ReadElementCount64(); + Skip(count); + return sizeof(count) + sizeof(T) * count; + } + + template void *DeserializeVector(void *begin, const void *end) + { + auto count = ReadElementCount64(); + auto required = reinterpret_cast(begin) + sizeof(count) + sizeof(T) * count; + if (required > end) + throw util::exception("Not enough memory "); + + *reinterpret_cast(begin) = count; + ReadInto(reinterpret_cast(reinterpret_cast(begin) + sizeof(decltype(count))), + count); + return required; + } + bool ReadAndCheckFingerprint() { auto loaded_fingerprint = ReadOne(); diff --git a/include/storage/shared_datatype.hpp b/include/storage/shared_datatype.hpp index fded3fa1c..141a70cd0 100644 --- a/include/storage/shared_datatype.hpp +++ b/include/storage/shared_datatype.hpp @@ -56,7 +56,9 @@ const constexpr char *block_id_to_name[] = {"NAME_CHAR_DATA", "LANE_DESCRIPTION_OFFSETS", "LANE_DESCRIPTION_MASKS", "TURN_WEIGHT_PENALTIES", - "TURN_DURATION_PENALTIES"}; + "TURN_DURATION_PENALTIES", + "MLD_CELL_PARTITION", + "MLD_CELL_STORAGE"}; struct DataLayout { @@ -101,6 +103,8 @@ struct DataLayout LANE_DESCRIPTION_MASKS, TURN_WEIGHT_PENALTIES, TURN_DURATION_PENALTIES, + MLD_CELL_PARTITION, + MLD_CELL_STORAGE, NUM_BLOCKS }; diff --git a/include/storage/storage_config.hpp b/include/storage/storage_config.hpp index e27c7ae38..397187d52 100644 --- a/include/storage/storage_config.hpp +++ b/include/storage/storage_config.hpp @@ -69,6 +69,8 @@ struct StorageConfig final boost::filesystem::path intersection_class_path; boost::filesystem::path turn_lane_data_path; boost::filesystem::path turn_lane_description_path; + boost::filesystem::path mld_partition_path; + boost::filesystem::path mld_storage_path; }; } } diff --git a/include/util/cell_storage.hpp b/include/util/cell_storage.hpp index bd99c3b79..286bf98af 100644 --- a/include/util/cell_storage.hpp +++ b/include/util/cell_storage.hpp @@ -3,9 +3,13 @@ #include "util/assert.hpp" #include "util/for_each_range.hpp" +#include "util/log.hpp" #include "util/multi_level_partition.hpp" +#include "util/shared_memory_vector_wrapper.hpp" #include "util/typedefs.hpp" +#include "storage/io.hpp" + #include #include @@ -19,7 +23,7 @@ namespace osrm namespace util { -class CellStorage +template class CellStorage { public: using WeightOffset = std::uint32_t; @@ -161,6 +165,8 @@ class CellStorage using Cell = CellImpl; using ConstCell = CellImpl; + CellStorage() {} + template CellStorage(const MultiLevelPartition &partition, const GraphT &base_graph) { @@ -286,6 +292,8 @@ class CellStorage { } + CellStorage(const boost::filesystem::path &path) { Read(path); } + ConstCell GetCell(LevelID level, CellID id) const { const auto level_index = LevelIDToIndex(level); @@ -308,12 +316,100 @@ class CellStorage cells[cell_index], weights.data(), source_boundary.data(), destination_boundary.data()}; } + std::size_t GetRequiredMemorySize(const boost::filesystem::path &path) const + { + const auto fingerprint = storage::io::FileReader::VerifyFingerprint; + storage::io::FileReader reader{path, fingerprint}; + + std::size_t memory_size = 0; + memory_size += reader.GetVectorMemorySize(); + memory_size += reader.GetVectorMemorySize(); + memory_size += reader.GetVectorMemorySize(); + memory_size += reader.GetVectorMemorySize(); + memory_size += reader.GetVectorMemorySize(); + return memory_size; + } + + template + typename std::enable_if::type + Read(const boost::filesystem::path &path, void *begin, const void *end) const + { + const auto fingerprint = storage::io::FileReader::VerifyFingerprint; + storage::io::FileReader reader{path, fingerprint}; + + begin = reader.DeserializeVector(begin, end); + begin = + reader.DeserializeVector(begin, end); + begin = reader.DeserializeVector(begin, + end); + begin = reader.DeserializeVector(begin, end); + begin = reader.DeserializeVector(begin, + end); + } + + template + typename std::enable_if::type InitializePointers(char *begin, const char *end) + { + auto weights_size = *reinterpret_cast(begin); + begin += sizeof(weights_size); + weights.reset(reinterpret_cast(begin), weights_size); + begin += sizeof(decltype(weights[0])) * weights_size; + + auto source_boundary_size = *reinterpret_cast(begin); + begin += sizeof(source_boundary_size); + source_boundary.reset(reinterpret_cast(begin), source_boundary_size); + begin += sizeof(decltype(source_boundary[0])) * source_boundary_size; + + auto destination_boundary_size = *reinterpret_cast(begin); + begin += sizeof(destination_boundary_size); + destination_boundary.reset(reinterpret_cast(begin), destination_boundary_size); + begin += sizeof(decltype(destination_boundary[0])) * destination_boundary_size; + + auto cells_size = *reinterpret_cast(begin); + begin += sizeof(cells_size); + cells.reset(reinterpret_cast(begin), cells_size); + begin += sizeof(decltype(cells[0])) * cells_size; + + auto level_to_cell_offset_size = *reinterpret_cast(begin); + begin += sizeof(level_to_cell_offset_size); + level_to_cell_offset.reset(reinterpret_cast(begin), + level_to_cell_offset_size); + begin += sizeof(decltype(level_to_cell_offset[0])) * level_to_cell_offset_size; + + BOOST_ASSERT(begin <= end); + } + + template + typename std::enable_if::type Read(const boost::filesystem::path &path) + { + const auto fingerprint = storage::io::FileReader::VerifyFingerprint; + storage::io::FileReader reader{path, fingerprint}; + + reader.DeserializeVector(weights); + reader.DeserializeVector(source_boundary); + reader.DeserializeVector(destination_boundary); + reader.DeserializeVector(cells); + reader.DeserializeVector(level_to_cell_offset); + } + + void Write(const boost::filesystem::path &path) const + { + const auto fingerprint = storage::io::FileWriter::GenerateFingerprint; + storage::io::FileWriter writer{path, fingerprint}; + + writer.SerializeVector(weights); + writer.SerializeVector(source_boundary); + writer.SerializeVector(destination_boundary); + writer.SerializeVector(cells); + writer.SerializeVector(level_to_cell_offset); + } + private: - std::vector weights; - std::vector source_boundary; - std::vector destination_boundary; - std::vector cells; - std::vector level_to_cell_offset; + typename util::ShM::vector weights; + typename util::ShM::vector source_boundary; + typename util::ShM::vector destination_boundary; + typename util::ShM::vector cells; + typename util::ShM::vector level_to_cell_offset; }; } } diff --git a/include/util/multi_level_partition.hpp b/include/util/multi_level_partition.hpp index ac65e6afc..a7deb0baa 100644 --- a/include/util/multi_level_partition.hpp +++ b/include/util/multi_level_partition.hpp @@ -3,8 +3,11 @@ #include "util/exception.hpp" #include "util/for_each_pair.hpp" +#include "util/shared_memory_vector_wrapper.hpp" #include "util/typedefs.hpp" +#include "storage/io.hpp" + #include #include #include @@ -73,12 +76,14 @@ class MultiLevelPartition virtual std::uint32_t GetNumberOfCells(LevelID level) const = 0; }; -class PackedMultiLevelPartition final : public MultiLevelPartition +template class PackedMultiLevelPartition final : public MultiLevelPartition { using PartitionID = std::uint64_t; static const constexpr std::uint8_t NUM_PARTITION_BITS = sizeof(PartitionID) * CHAR_BIT; public: + PackedMultiLevelPartition() {} + // cell_sizes is index by level (starting at 0, the base graph). // However level 0 always needs to have cell size 1, since it is the // basegraph. @@ -90,6 +95,8 @@ class PackedMultiLevelPartition final : public MultiLevelPartition initializePartitionIDs(partitions); } + PackedMultiLevelPartition(const boost::filesystem::path &file_name) { Read(file_name); } + // returns the index of the cell the vertex is contained at level l CellID GetCell(LevelID l, NodeID node) const final override { @@ -139,6 +146,89 @@ class PackedMultiLevelPartition final : public MultiLevelPartition return cell_to_children[offset + cell + 1]; } + std::size_t GetRequiredMemorySize(const boost::filesystem::path &path) const + { + const auto fingerprint = storage::io::FileReader::VerifyFingerprint; + storage::io::FileReader reader{path, fingerprint}; + + std::size_t memory_size = 0; + memory_size += reader.GetVectorMemorySize(); + memory_size += reader.GetVectorMemorySize(); + memory_size += reader.GetVectorMemorySize(); + memory_size += reader.GetVectorMemorySize(); + return memory_size; + } + + template + typename std::enable_if::type + Read(const boost::filesystem::path &path, void *begin, const void *end) const + { + const auto fingerprint = storage::io::FileReader::VerifyFingerprint; + storage::io::FileReader reader{path, fingerprint}; + + begin = reader.DeserializeVector(begin, end); + begin = reader.DeserializeVector(begin, end); + begin = reader.DeserializeVector( + begin, end); + begin = + reader.DeserializeVector(begin, end); + } + + template + typename std::enable_if::type InitializePointers(char *begin, const char *end) + { + auto level_offsets_size = *reinterpret_cast(begin); + begin += sizeof(level_offsets_size); + level_offsets.reset(begin, level_offsets_size); + begin += sizeof(decltype(level_offsets[0])) * level_offsets_size; + + auto partition_size = *reinterpret_cast(begin); + begin += sizeof(partition_size); + partition.reset(begin, partition_size); + begin += sizeof(decltype(partition[0])) * partition_size; + + auto level_to_children_offset_size = *reinterpret_cast(begin); + begin += sizeof(level_to_children_offset_size); + level_to_children_offset.reset(begin, level_to_children_offset_size); + begin += sizeof(decltype(level_to_children_offset[0])) * level_to_children_offset_size; + + auto cell_to_children_size = *reinterpret_cast(begin); + begin += sizeof(cell_to_children_size); + cell_to_children.reset(begin, cell_to_children_size); + begin += sizeof(decltype(cell_to_children[0])) * level_to_children_offset_size; + + BOOST_ASSERT(begin <= end); + + level_masks = makeLevelMasks(); + bit_to_level = makeBitToLevel(); + } + + template + typename std::enable_if::type Read(const boost::filesystem::path &path) + { + const auto fingerprint = storage::io::FileReader::VerifyFingerprint; + storage::io::FileReader reader{path, fingerprint}; + + reader.DeserializeVector(level_offsets); + reader.DeserializeVector(partition); + reader.DeserializeVector(level_to_children_offset); + reader.DeserializeVector(cell_to_children); + + level_masks = makeLevelMasks(); + bit_to_level = makeBitToLevel(); + } + + void Write(const boost::filesystem::path &path) const + { + const auto fingerprint = storage::io::FileWriter::GenerateFingerprint; + storage::io::FileWriter writer{path, fingerprint}; + + writer.SerializeVector(level_offsets); + writer.SerializeVector(partition); + writer.SerializeVector(level_to_children_offset); + writer.SerializeVector(cell_to_children); + } + private: inline std::size_t LevelIDToIndex(LevelID l) const { return l - 1; } @@ -306,11 +396,11 @@ class PackedMultiLevelPartition final : public MultiLevelPartition } } - std::vector partition; - std::vector level_offsets; + typename util::ShM::vector level_offsets; + typename util::ShM::vector partition; + typename util::ShM::vector level_to_children_offset; + typename util::ShM::vector cell_to_children; std::vector level_masks; - std::vector level_to_children_offset; - std::vector cell_to_children; std::array bit_to_level; }; } diff --git a/include/util/shared_memory_vector_wrapper.hpp b/include/util/shared_memory_vector_wrapper.hpp index cb362fc38..a86ac4586 100644 --- a/include/util/shared_memory_vector_wrapper.hpp +++ b/include/util/shared_memory_vector_wrapper.hpp @@ -58,6 +58,7 @@ template class SharedMemoryWrapper std::size_t m_size; public: + using value_type = DataT; using iterator = ShMemIterator; using reverse_iterator = boost::reverse_iterator; @@ -71,6 +72,12 @@ template class SharedMemoryWrapper m_size = size; } + void reset(void *ptr, std::size_t size) + { + m_ptr = reinterpret_cast(ptr); + m_size = size; + } + DataT &at(const std::size_t index) { return m_ptr[index]; } const DataT &at(const std::size_t index) const { return m_ptr[index]; } diff --git a/src/partition/partitioner.cpp b/src/partition/partitioner.cpp index ac77843e6..66fc450a2 100644 --- a/src/partition/partitioner.cpp +++ b/src/partition/partitioner.cpp @@ -6,18 +6,22 @@ #include "partition/node_based_graph_to_edge_based_graph_mapping_reader.hpp" #include "partition/recursive_bisection.hpp" +#include "util/cell_storage.hpp" #include "util/coordinate.hpp" #include "util/geojson_debug_logger.hpp" #include "util/geojson_debug_policies.hpp" #include "util/integer_range.hpp" #include "util/json_container.hpp" #include "util/log.hpp" +#include "util/multi_level_partition.hpp" #include #include +#include #include #include +#include #include "util/geojson_debug_logger.hpp" #include "util/geojson_debug_policies.hpp" @@ -181,6 +185,88 @@ int Partitioner::Run(const PartitionConfig &config) } } + // FIXME The CellID computation code need to be replaced by a more sophisticated method + { + BOOST_ASSERT(edge_based_partition_ids.size() == edge_based_graph->GetNumberOfNodes()); + + using namespace osrm::partition; + + // find bit size of bisection ids + int first_nonzero_position = sizeof(BisectionID) * CHAR_BIT; + for (auto id : edge_based_partition_ids) + { + first_nonzero_position = id == 0 ? first_nonzero_position + : std::min(first_nonzero_position, __builtin_ctz(id)); + } + BOOST_ASSERT(first_nonzero_position != sizeof(BisectionID) * CHAR_BIT); + + // split bisection id bits into groups starting from SCC and stop at level 1 + BOOST_ASSERT(recursive_bisection.SCCDepth() != 0); + int mask_from = sizeof(BisectionID) * CHAR_BIT - recursive_bisection.SCCDepth(); + boost::container::small_vector level_masks; + for (int mask_to = sizeof(BisectionID) * CHAR_BIT; mask_to > first_nonzero_position; + mask_to = mask_from, mask_from -= 3) // TODO: find better grouping + { + auto bit = std::max(first_nonzero_position, mask_from); + level_masks.push_back(((1u << (sizeof(BisectionID) * CHAR_BIT - bit)) - 1) << bit); + } + + util::Log() << "Bisection IDs split for SCC depth " << recursive_bisection.SCCDepth() + << " and first non-zero bit position " << first_nonzero_position + << " number of levels is " << level_masks.size(); + for (auto x : level_masks) + std::cout << std::setw(8) << std::hex << x << std::dec << "\n"; + + // collect cell ids as masked bisection ids + std::vector> partitions( + level_masks.size(), std::vector(edge_based_partition_ids.size())); + std::vector> partition_sets(level_masks.size()); + for (std::size_t index = 0; index < edge_based_partition_ids.size(); ++index) + { + auto bisection_id = edge_based_partition_ids[index]; + for (std::size_t level = 0; level < level_masks.size(); ++level) + { + osrm::util::CellID cell_id = + bisection_id & level_masks[level_masks.size() - 1 - level]; + partitions[level][index] = cell_id; + partition_sets[level].insert(cell_id); + } + } + + std::vector level_to_num_cells; + std::transform(partition_sets.begin(), + partition_sets.end(), + std::back_inserter(level_to_num_cells), + [](const std::unordered_set &partition_set) { + return partition_set.size(); + }); + std::cout << "# of cell on levels\n"; + for (std::size_t level = 0; level < partition_sets.size(); ++level) + { + std::cout << level_to_num_cells[level] << ": "; + for (auto x : partition_sets[level]) + std::cout << " " << x; + std::cout << "\n"; + } + + TIMER_START(packed_mlp); + osrm::util::PackedMultiLevelPartition mlp{partitions, level_to_num_cells}; + TIMER_STOP(packed_mlp); + util::Log() << "PackedMultiLevelPartition constructed in " << TIMER_SEC(packed_mlp) + << " seconds"; + + TIMER_START(cell_storage); + osrm::util::CellStorage storage(mlp, *edge_based_graph); + TIMER_STOP(cell_storage); + util::Log() << "CellStorage constructed in " << TIMER_SEC(cell_storage) << " seconds"; + + TIMER_START(writing_mld_data); + mlp.Write(config.mld_partition_path); + storage.Write(config.mld_storage_path); + TIMER_STOP(writing_mld_data); + util::Log() << "MLD data writing took " << TIMER_SEC(writing_mld_data) << " seconds"; + } + return 0; } diff --git a/src/partition/recursive_bisection.cpp b/src/partition/recursive_bisection.cpp index 3698828b8..c491b4582 100644 --- a/src/partition/recursive_bisection.cpp +++ b/src/partition/recursive_bisection.cpp @@ -105,5 +105,7 @@ const std::vector &RecursiveBisection::BisectionIDs() const return internal_state.BisectionIDs(); } +std::uint32_t RecursiveBisection::SCCDepth() const { return internal_state.SCCDepth(); } + } // namespace partition } // namespace osrm diff --git a/src/storage/storage.cpp b/src/storage/storage.cpp index ed064ab48..c49c4929f 100644 --- a/src/storage/storage.cpp +++ b/src/storage/storage.cpp @@ -12,12 +12,14 @@ #include "storage/shared_memory.hpp" #include "storage/shared_monitor.hpp" #include "engine/datafacade/datafacade_base.hpp" +#include "util/cell_storage.hpp" #include "util/coordinate.hpp" #include "util/exception.hpp" #include "util/exception_utils.hpp" #include "util/fingerprint.hpp" #include "util/io.hpp" #include "util/log.hpp" +#include "util/multi_level_partition.hpp" #include "util/packed_vector.hpp" #include "util/range_table.hpp" #include "util/shared_memory_vector_wrapper.hpp" @@ -393,6 +395,27 @@ void Storage::PopulateLayout(DataLayout &layout) layout.SetBlockSize(DataLayout::TURN_LANE_DATA, lane_tuple_count); } + + { + // Loading MLD Data + if (boost::filesystem::exists(config.mld_partition_path)) + { + auto mld_partition_size = util::PackedMultiLevelPartition().GetRequiredMemorySize( + config.mld_partition_path); + layout.SetBlockSize(DataLayout::MLD_CELL_PARTITION, mld_partition_size); + } + else + layout.SetBlockSize(DataLayout::MLD_CELL_PARTITION, 0); + + if (boost::filesystem::exists(config.mld_storage_path)) + { + auto mld_cell_storage_size = + util::CellStorage().GetRequiredMemorySize(config.mld_storage_path); + layout.SetBlockSize(DataLayout::MLD_CELL_STORAGE, mld_cell_storage_size); + } + else + layout.SetBlockSize(DataLayout::MLD_CELL_STORAGE, 0); + } } void Storage::PopulateData(const DataLayout &layout, char *memory_ptr) @@ -840,6 +863,28 @@ void Storage::PopulateData(const DataLayout &layout, char *memory_ptr) std::copy(entry_class_table.begin(), entry_class_table.end(), entry_class_ptr); } } + + { + // Loading MLD Data + const auto mld_partition_ptr = + layout.GetBlockPtr(memory_ptr, DataLayout::MLD_CELL_PARTITION); + const auto mld_partition_size = layout.GetBlockSize(DataLayout::MLD_CELL_PARTITION); + if (boost::filesystem::exists(config.mld_partition_path)) + { + util::PackedMultiLevelPartition().Read( + config.mld_partition_path, mld_partition_ptr, mld_partition_ptr + mld_partition_size); + } + + const auto mld_cell_storage_ptr = + layout.GetBlockPtr(memory_ptr, DataLayout::MLD_CELL_STORAGE); + const auto mld_cell_storage_size = layout.GetBlockSize(DataLayout::MLD_CELL_STORAGE); + if (boost::filesystem::exists(config.mld_storage_path)) + { + util::CellStorage().Read(config.mld_storage_path, + mld_cell_storage_ptr, + mld_cell_storage_ptr + mld_cell_storage_size); + } + } } } } diff --git a/src/storage/storage_config.cpp b/src/storage/storage_config.cpp index 714d4fb5a..4f8743f3b 100644 --- a/src/storage/storage_config.cpp +++ b/src/storage/storage_config.cpp @@ -19,7 +19,9 @@ StorageConfig::StorageConfig(const boost::filesystem::path &base) datasource_indexes_path{base.string() + ".datasource_indexes"}, names_data_path{base.string() + ".names"}, properties_path{base.string() + ".properties"}, intersection_class_path{base.string() + ".icd"}, turn_lane_data_path{base.string() + ".tld"}, - turn_lane_description_path{base.string() + ".tls"} + turn_lane_description_path{base.string() + ".tls"}, + mld_partition_path{base.string() + ".mld_partition"}, + mld_storage_path{base.string() + ".mld_storage"} { } diff --git a/unit_tests/util/cell_storage.cpp b/unit_tests/util/cell_storage.cpp index 6c0d833f5..bf8fafbff 100644 --- a/unit_tests/util/cell_storage.cpp +++ b/unit_tests/util/cell_storage.cpp @@ -107,7 +107,7 @@ BOOST_AUTO_TEST_CASE(mutable_cell_storage) auto graph = makeGraph(edges); // test non-const storage - CellStorage storage(mlp, graph); + CellStorage storage(mlp, graph); // Level 1 auto cell_1_0 = storage.GetCell(1, 0); @@ -250,7 +250,7 @@ BOOST_AUTO_TEST_CASE(immutable_cell_storage) // 3/0: 3 : 1,0,1 // test const storage - const CellStorage const_storage(mlp, graph); + const CellStorage const_storage(mlp, graph); auto const_cell_1_0 = const_storage.GetCell(1, 0); auto const_cell_1_1 = const_storage.GetCell(1, 1); diff --git a/unit_tests/util/multi_level_partition.cpp b/unit_tests/util/multi_level_partition.cpp index aaddc0420..a874dad22 100644 --- a/unit_tests/util/multi_level_partition.cpp +++ b/unit_tests/util/multi_level_partition.cpp @@ -24,7 +24,7 @@ BOOST_AUTO_TEST_CASE(packed_mlp) std::vector l2{{0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3}}; std::vector l3{{0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}}; std::vector l4{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; - PackedMultiLevelPartition mlp{{l1, l2, l3, l4}, {6, 4, 2, 1}}; + PackedMultiLevelPartition mlp{{l1, l2, l3, l4}, {6, 4, 2, 1}}; BOOST_CHECK_EQUAL(mlp.GetNumberOfCells(1), 6); BOOST_CHECK_EQUAL(mlp.GetNumberOfCells(2), 4);