Load data in two separate data regions
This commit is contained in:
committed by
Patrick Niklaus
parent
c7daa521ad
commit
fea07f343b
@@ -1,5 +1,7 @@
|
||||
#include "engine/datafacade/mmap_memory_allocator.hpp"
|
||||
|
||||
#include "storage/io.hpp"
|
||||
#include "storage/serialization.hpp"
|
||||
#include "storage/storage.hpp"
|
||||
|
||||
#include "util/log.hpp"
|
||||
@@ -22,31 +24,43 @@ MMapMemoryAllocator::MMapMemoryAllocator(const storage::StorageConfig &config,
|
||||
if (!boost::filesystem::exists(memory_file))
|
||||
{
|
||||
storage::DataLayout initial_layout;
|
||||
storage.PopulateLayout(initial_layout);
|
||||
storage.PopulateStaticLayout(initial_layout);
|
||||
storage.PopulateUpdatableLayout(initial_layout);
|
||||
|
||||
auto data_size = initial_layout.GetSizeOfLayout();
|
||||
auto total_size = data_size + sizeof(storage::DataLayout);
|
||||
|
||||
storage::io::BufferWriter writer;
|
||||
storage::serialization::write(writer, initial_layout);
|
||||
auto encoded_layout = writer.GetBuffer();
|
||||
|
||||
auto total_size = data_size + encoded_layout.size();
|
||||
|
||||
mapped_memory = util::mmapFile<char>(memory_file, mapped_memory_file, total_size);
|
||||
|
||||
data_layout = reinterpret_cast<storage::DataLayout *>(mapped_memory.data());
|
||||
*data_layout = initial_layout;
|
||||
storage.PopulateData(*data_layout, GetMemory());
|
||||
std::copy(encoded_layout.begin(), encoded_layout.end(), mapped_memory.data());
|
||||
|
||||
index = storage::SharedDataIndex(
|
||||
{{mapped_memory.data() + encoded_layout.size(), std::move(initial_layout)}});
|
||||
|
||||
storage.PopulateStaticData(index);
|
||||
storage.PopulateUpdatableData(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
mapped_memory = util::mmapFile<char>(memory_file, mapped_memory_file);
|
||||
data_layout = reinterpret_cast<storage::DataLayout *>(mapped_memory.data());
|
||||
|
||||
storage::DataLayout layout;
|
||||
storage::io::BufferReader reader(mapped_memory.data());
|
||||
storage::serialization::read(reader, layout);
|
||||
auto layout_size = reader.GetPosition();
|
||||
|
||||
index = storage::SharedDataIndex({{mapped_memory.data() + layout_size, std::move(layout)}});
|
||||
}
|
||||
}
|
||||
|
||||
MMapMemoryAllocator::~MMapMemoryAllocator() {}
|
||||
|
||||
storage::DataLayout &MMapMemoryAllocator::GetLayout() { return *data_layout; }
|
||||
char *MMapMemoryAllocator::GetMemory()
|
||||
{
|
||||
return mapped_memory.data() + sizeof(storage::DataLayout);
|
||||
}
|
||||
const storage::SharedDataIndex &MMapMemoryAllocator::GetIndex() { return index; }
|
||||
|
||||
} // namespace datafacade
|
||||
} // namespace engine
|
||||
|
||||
@@ -15,17 +15,22 @@ ProcessMemoryAllocator::ProcessMemoryAllocator(const storage::StorageConfig &con
|
||||
storage::Storage storage(config);
|
||||
|
||||
// Calculate the layout/size of the memory block
|
||||
storage.PopulateLayout(internal_layout);
|
||||
storage::DataLayout layout;
|
||||
storage.PopulateStaticLayout(layout);
|
||||
storage.PopulateUpdatableLayout(layout);
|
||||
|
||||
// Allocate the memory block, then load data from files into it
|
||||
internal_memory = std::make_unique<char[]>(internal_layout.GetSizeOfLayout());
|
||||
storage.PopulateData(internal_layout, internal_memory.get());
|
||||
internal_memory = std::make_unique<char[]>(layout.GetSizeOfLayout());
|
||||
|
||||
index = storage::SharedDataIndex({{internal_memory.get(), std::move(layout)}});
|
||||
|
||||
storage.PopulateStaticData(index);
|
||||
storage.PopulateUpdatableData(index);
|
||||
}
|
||||
|
||||
ProcessMemoryAllocator::~ProcessMemoryAllocator() {}
|
||||
|
||||
const storage::DataLayout &ProcessMemoryAllocator::GetLayout() { return internal_layout; }
|
||||
char *ProcessMemoryAllocator::GetMemory() { return internal_memory.get(); }
|
||||
const storage::SharedDataIndex &ProcessMemoryAllocator::GetIndex() { return index; }
|
||||
|
||||
} // namespace datafacade
|
||||
} // namespace engine
|
||||
|
||||
@@ -13,27 +13,32 @@ namespace engine
|
||||
namespace datafacade
|
||||
{
|
||||
|
||||
SharedMemoryAllocator::SharedMemoryAllocator(storage::SharedRegionRegister::ShmKey data_shm_key)
|
||||
SharedMemoryAllocator::SharedMemoryAllocator(
|
||||
const std::vector<storage::SharedRegionRegister::ShmKey> &shm_keys)
|
||||
{
|
||||
util::Log(logDEBUG) << "Loading new data for region " << (int)data_shm_key;
|
||||
std::vector<storage::SharedDataIndex::AllocatedRegion> regions;
|
||||
|
||||
BOOST_ASSERT(storage::SharedMemory::RegionExists(data_shm_key));
|
||||
m_large_memory = storage::makeSharedMemory(data_shm_key);
|
||||
for (const auto shm_key : shm_keys)
|
||||
{
|
||||
util::Log(logDEBUG) << "Loading new data for region " << (int)shm_key;
|
||||
BOOST_ASSERT(storage::SharedMemory::RegionExists(shm_key));
|
||||
auto mem = storage::makeSharedMemory(shm_key);
|
||||
|
||||
storage::io::BufferReader reader(reinterpret_cast<char *>(m_large_memory->Ptr()),
|
||||
m_large_memory->Size());
|
||||
storage::serialization::read(reader, data_layout);
|
||||
layout_size = reader.GetPosition();
|
||||
util::Log(logDEBUG) << "Data layout has size " << layout_size;
|
||||
storage::io::BufferReader reader(reinterpret_cast<char *>(mem->Ptr()), mem->Size());
|
||||
storage::DataLayout layout;
|
||||
storage::serialization::read(reader, layout);
|
||||
auto layout_size = reader.GetPosition();
|
||||
|
||||
regions.push_back({reinterpret_cast<char *>(mem->Ptr()) + layout_size, std::move(layout)});
|
||||
memory_regions.push_back(std::move(mem));
|
||||
}
|
||||
|
||||
index = storage::SharedDataIndex{std::move(regions)};
|
||||
}
|
||||
|
||||
SharedMemoryAllocator::~SharedMemoryAllocator() {}
|
||||
|
||||
const storage::DataLayout &SharedMemoryAllocator::GetLayout() { return data_layout; }
|
||||
char *SharedMemoryAllocator::GetMemory()
|
||||
{
|
||||
return reinterpret_cast<char *>(m_large_memory->Ptr()) + layout_size;
|
||||
}
|
||||
const storage::SharedDataIndex &SharedMemoryAllocator::GetIndex() { return index; }
|
||||
|
||||
} // namespace datafacade
|
||||
} // namespace engine
|
||||
|
||||
+257
-200
@@ -42,7 +42,9 @@ namespace storage
|
||||
{
|
||||
namespace
|
||||
{
|
||||
inline void readBlocks(const boost::filesystem::path &path, DataLayout &layout)
|
||||
using Monitor = SharedMonitor<SharedRegionRegister>;
|
||||
|
||||
void readBlocks(const boost::filesystem::path &path, DataLayout &layout)
|
||||
{
|
||||
tar::FileReader reader(path, tar::FileReader::VerifyFingerprint);
|
||||
|
||||
@@ -59,9 +61,128 @@ inline void readBlocks(const boost::filesystem::path &path, DataLayout &layout)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct RegionHandle
|
||||
{
|
||||
std::unique_ptr<SharedMemory> memory;
|
||||
char *data_ptr;
|
||||
std::uint8_t shm_key;
|
||||
};
|
||||
|
||||
auto setupRegion(SharedRegionRegister &shared_register, const DataLayout &layout)
|
||||
{
|
||||
// This is safe because we have an exclusive lock for all osrm-datastore processes.
|
||||
auto shm_key = shared_register.ReserveKey();
|
||||
|
||||
// ensure that the shared memory region we want to write to is really removed
|
||||
// this is only needef for failure recovery because we actually wait for all clients
|
||||
// to detach at the end of the function
|
||||
if (storage::SharedMemory::RegionExists(shm_key))
|
||||
{
|
||||
util::Log(logWARNING) << "Old shared memory region " << (int)shm_key << " still exists.";
|
||||
util::UnbufferedLog() << "Retrying removal... ";
|
||||
storage::SharedMemory::Remove(shm_key);
|
||||
util::UnbufferedLog() << "ok.";
|
||||
}
|
||||
|
||||
io::BufferWriter writer;
|
||||
serialization::write(writer, layout);
|
||||
auto encoded_static_layout = writer.GetBuffer();
|
||||
|
||||
// Allocate shared memory block
|
||||
auto regions_size = encoded_static_layout.size() + layout.GetSizeOfLayout();
|
||||
util::Log() << "Data layout has a size of " << encoded_static_layout.size() << " bytes";
|
||||
util::Log() << "Allocating shared memory of " << regions_size << " bytes";
|
||||
auto memory = makeSharedMemory(shm_key, regions_size);
|
||||
|
||||
// Copy memory static_layout to shared memory and populate data
|
||||
char *shared_memory_ptr = static_cast<char *>(memory->Ptr());
|
||||
auto data_ptr =
|
||||
std::copy_n(encoded_static_layout.data(), encoded_static_layout.size(), shared_memory_ptr);
|
||||
|
||||
return RegionHandle{std::move(memory), data_ptr, shm_key};
|
||||
}
|
||||
|
||||
using Monitor = SharedMonitor<SharedRegionRegister>;
|
||||
bool swapData(Monitor &monitor,
|
||||
SharedRegionRegister &shared_register,
|
||||
const std::map<std::string, RegionHandle> &handles,
|
||||
int max_wait)
|
||||
{
|
||||
std::vector<RegionHandle> old_handles;
|
||||
|
||||
{ // Lock for write access shared region mutex
|
||||
boost::interprocess::scoped_lock<Monitor::mutex_type> lock(monitor.get_mutex(),
|
||||
boost::interprocess::defer_lock);
|
||||
|
||||
if (max_wait >= 0)
|
||||
{
|
||||
if (!lock.timed_lock(boost::posix_time::microsec_clock::universal_time() +
|
||||
boost::posix_time::seconds(max_wait)))
|
||||
{
|
||||
util::Log(logERROR) << "Could not aquire current region lock after " << max_wait
|
||||
<< " seconds. Data update failed.";
|
||||
|
||||
for (auto &pair : handles)
|
||||
{
|
||||
SharedMemory::Remove(pair.second.shm_key);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lock.lock();
|
||||
}
|
||||
|
||||
for (auto &pair : handles)
|
||||
{
|
||||
auto region_id = shared_register.Find(pair.first);
|
||||
if (region_id == SharedRegionRegister::INVALID_REGION_ID)
|
||||
{
|
||||
region_id = shared_register.Register(pair.first, pair.second.shm_key);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto &shared_region = shared_register.GetRegion(region_id);
|
||||
|
||||
old_handles.push_back(RegionHandle{
|
||||
makeSharedMemory(shared_region.shm_key), nullptr, shared_region.shm_key});
|
||||
|
||||
shared_region.shm_key = pair.second.shm_key;
|
||||
shared_region.timestamp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
util::Log() << "All data loaded. Notify all client about new data in:";
|
||||
for (const auto &pair : handles)
|
||||
{
|
||||
util::Log() << pair.first << "\t" << static_cast<int>(pair.second.shm_key);
|
||||
}
|
||||
monitor.notify_all();
|
||||
|
||||
for (auto &old_handle : old_handles)
|
||||
{
|
||||
util::UnbufferedLog() << "Marking old shared memory region "
|
||||
<< static_cast<int>(old_handle.shm_key) << " for removal... ";
|
||||
|
||||
// SHMCTL(2): Mark the segment to be destroyed. The segment will actually be destroyed
|
||||
// only after the last process detaches it.
|
||||
storage::SharedMemory::Remove(old_handle.shm_key);
|
||||
util::UnbufferedLog() << "ok.";
|
||||
|
||||
util::UnbufferedLog() << "Waiting for clients to detach... ";
|
||||
old_handle.memory->WaitForDetach();
|
||||
util::UnbufferedLog() << " ok.";
|
||||
|
||||
shared_register.ReleaseKey(old_handle.shm_key);
|
||||
}
|
||||
|
||||
util::Log() << "All clients switched.";
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Storage::Storage(StorageConfig config_) : config(std::move(config_)) {}
|
||||
|
||||
@@ -103,106 +224,26 @@ int Storage::Run(int max_wait, const std::string &dataset_name)
|
||||
Monitor monitor(SharedRegionRegister{});
|
||||
auto &shared_register = monitor.data();
|
||||
|
||||
// This is safe because we have an exclusive lock for all osrm-datastore processes.
|
||||
auto shm_key = shared_register.ReserveKey();
|
||||
|
||||
// ensure that the shared memory region we want to write to is really removed
|
||||
// this is only needef for failure recovery because we actually wait for all clients
|
||||
// to detach at the end of the function
|
||||
if (storage::SharedMemory::RegionExists(shm_key))
|
||||
{
|
||||
util::Log(logWARNING) << "Old shared memory region " << shm_key << " still exists.";
|
||||
util::UnbufferedLog() << "Retrying removal... ";
|
||||
storage::SharedMemory::Remove(shm_key);
|
||||
util::UnbufferedLog() << "ok.";
|
||||
}
|
||||
|
||||
util::Log() << "Loading data into " << static_cast<int>(shm_key);
|
||||
|
||||
// Populate a memory layout into stack memory
|
||||
DataLayout layout;
|
||||
PopulateLayout(layout);
|
||||
DataLayout static_layout;
|
||||
PopulateStaticLayout(static_layout);
|
||||
DataLayout updatable_layout;
|
||||
PopulateUpdatableLayout(updatable_layout);
|
||||
|
||||
io::BufferWriter writer;
|
||||
serialization::write(writer, layout);
|
||||
auto encoded_layout = writer.GetBuffer();
|
||||
auto static_handle = setupRegion(shared_register, static_layout);
|
||||
auto updatable_handle = setupRegion(shared_register, updatable_layout);
|
||||
|
||||
// Allocate shared memory block
|
||||
auto regions_size = encoded_layout.size() + layout.GetSizeOfLayout();
|
||||
util::Log() << "Data layout has a size of " << encoded_layout.size() << " bytes";
|
||||
util::Log() << "Allocating shared memory of " << regions_size << " bytes";
|
||||
auto data_memory = makeSharedMemory(shm_key, regions_size);
|
||||
SharedDataIndex index{
|
||||
{{static_handle.data_ptr, static_layout}, {updatable_handle.data_ptr, updatable_layout}}};
|
||||
|
||||
// Copy memory layout to shared memory and populate data
|
||||
char *shared_memory_ptr = static_cast<char *>(data_memory->Ptr());
|
||||
std::copy_n(encoded_layout.data(), encoded_layout.size(), shared_memory_ptr);
|
||||
PopulateData(layout, shared_memory_ptr + encoded_layout.size());
|
||||
PopulateStaticData(index);
|
||||
PopulateUpdatableData(index);
|
||||
|
||||
std::uint32_t next_timestamp = 0;
|
||||
std::uint8_t in_use_key = SharedRegionRegister::MAX_SHM_KEYS;
|
||||
std::map<std::string, RegionHandle> handles;
|
||||
handles[dataset_name + "/static"] = std::move(static_handle);
|
||||
handles[dataset_name + "/updatable"] = std::move(updatable_handle);
|
||||
|
||||
{ // Lock for write access shared region mutex
|
||||
boost::interprocess::scoped_lock<Monitor::mutex_type> lock(monitor.get_mutex(),
|
||||
boost::interprocess::defer_lock);
|
||||
|
||||
if (max_wait >= 0)
|
||||
{
|
||||
if (!lock.timed_lock(boost::posix_time::microsec_clock::universal_time() +
|
||||
boost::posix_time::seconds(max_wait)))
|
||||
{
|
||||
util::Log(logERROR) << "Could not aquire current region lock after " << max_wait
|
||||
<< " seconds. Data update failed.";
|
||||
SharedMemory::Remove(shm_key);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lock.lock();
|
||||
}
|
||||
|
||||
auto region_id = shared_register.Find(dataset_name + "/data");
|
||||
if (region_id == SharedRegionRegister::INVALID_REGION_ID)
|
||||
{
|
||||
region_id = shared_register.Register(dataset_name + "/data", shm_key);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto &shared_region = shared_register.GetRegion(region_id);
|
||||
next_timestamp = shared_region.timestamp + 1;
|
||||
in_use_key = shared_region.shm_key;
|
||||
shared_region.shm_key = shm_key;
|
||||
shared_region.timestamp = next_timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
util::Log() << "All data loaded. Notify all client about new data in "
|
||||
<< static_cast<int>(shm_key) << " with timestamp " << next_timestamp;
|
||||
monitor.notify_all();
|
||||
|
||||
// SHMCTL(2): Mark the segment to be destroyed. The segment will actually be destroyed
|
||||
// only after the last process detaches it.
|
||||
if (in_use_key != SharedRegionRegister::MAX_SHM_KEYS &&
|
||||
storage::SharedMemory::RegionExists(in_use_key))
|
||||
{
|
||||
util::UnbufferedLog() << "Marking old shared memory region " << static_cast<int>(in_use_key)
|
||||
<< " for removal... ";
|
||||
|
||||
// aquire a handle for the old shared memory region before we mark it for deletion
|
||||
// we will need this to wait for all users to detach
|
||||
auto in_use_shared_memory = makeSharedMemory(in_use_key);
|
||||
|
||||
storage::SharedMemory::Remove(in_use_key);
|
||||
util::UnbufferedLog() << "ok.";
|
||||
|
||||
util::UnbufferedLog() << "Waiting for clients to detach... ";
|
||||
in_use_shared_memory->WaitForDetach();
|
||||
util::UnbufferedLog() << " ok.";
|
||||
|
||||
shared_register.ReleaseKey(in_use_key);
|
||||
}
|
||||
|
||||
util::Log() << "All clients switched.";
|
||||
swapData(monitor, shared_register, handles, max_wait);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -212,35 +253,28 @@ int Storage::Run(int max_wait, const std::string &dataset_name)
|
||||
* memory needs to be allocated, and the position of each data structure
|
||||
* in that big block. It updates the fields in the DataLayout parameter.
|
||||
*/
|
||||
void Storage::PopulateLayout(DataLayout &layout)
|
||||
void Storage::PopulateStaticLayout(DataLayout &static_layout)
|
||||
{
|
||||
{
|
||||
auto absolute_file_index_path =
|
||||
boost::filesystem::absolute(config.GetPath(".osrm.fileIndex"));
|
||||
|
||||
layout.SetBlock("/common/rtree/file_index_path",
|
||||
make_block<char>(absolute_file_index_path.string().length() + 1));
|
||||
static_layout.SetBlock("/common/rtree/file_index_path",
|
||||
make_block<char>(absolute_file_index_path.string().length() + 1));
|
||||
}
|
||||
|
||||
constexpr bool REQUIRED = true;
|
||||
constexpr bool OPTIONAL = false;
|
||||
std::vector<std::pair<bool, boost::filesystem::path>> tar_files = {
|
||||
{OPTIONAL, config.GetPath(".osrm.mldgr")},
|
||||
{OPTIONAL, config.GetPath(".osrm.cells")},
|
||||
{OPTIONAL, config.GetPath(".osrm.partition")},
|
||||
{OPTIONAL, config.GetPath(".osrm.cell_metrics")},
|
||||
{OPTIONAL, config.GetPath(".osrm.hsgr")},
|
||||
{REQUIRED, config.GetPath(".osrm.icd")},
|
||||
{REQUIRED, config.GetPath(".osrm.properties")},
|
||||
{REQUIRED, config.GetPath(".osrm.nbg_nodes")},
|
||||
{REQUIRED, config.GetPath(".osrm.datasource_names")},
|
||||
{REQUIRED, config.GetPath(".osrm.geometry")},
|
||||
{REQUIRED, config.GetPath(".osrm.ebg_nodes")},
|
||||
{REQUIRED, config.GetPath(".osrm.tls")},
|
||||
{REQUIRED, config.GetPath(".osrm.tld")},
|
||||
{REQUIRED, config.GetPath(".osrm.maneuver_overrides")},
|
||||
{REQUIRED, config.GetPath(".osrm.turn_weight_penalties")},
|
||||
{REQUIRED, config.GetPath(".osrm.turn_duration_penalties")},
|
||||
{REQUIRED, config.GetPath(".osrm.edges")},
|
||||
{REQUIRED, config.GetPath(".osrm.names")},
|
||||
{REQUIRED, config.GetPath(".osrm.ramIndex")},
|
||||
@@ -250,7 +284,7 @@ void Storage::PopulateLayout(DataLayout &layout)
|
||||
{
|
||||
if (boost::filesystem::exists(file.second))
|
||||
{
|
||||
readBlocks(file.second, layout);
|
||||
readBlocks(file.second, static_layout);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -263,26 +297,51 @@ void Storage::PopulateLayout(DataLayout &layout)
|
||||
}
|
||||
}
|
||||
|
||||
void Storage::PopulateData(const DataLayout &layout, char *memory_ptr)
|
||||
void Storage::PopulateUpdatableLayout(DataLayout &updatable_layout)
|
||||
{
|
||||
BOOST_ASSERT(memory_ptr != nullptr);
|
||||
constexpr bool REQUIRED = true;
|
||||
constexpr bool OPTIONAL = false;
|
||||
std::vector<std::pair<bool, boost::filesystem::path>> tar_files = {
|
||||
{OPTIONAL, config.GetPath(".osrm.mldgr")},
|
||||
{OPTIONAL, config.GetPath(".osrm.cell_metrics")},
|
||||
{OPTIONAL, config.GetPath(".osrm.hsgr")},
|
||||
{REQUIRED, config.GetPath(".osrm.datasource_names")},
|
||||
{REQUIRED, config.GetPath(".osrm.geometry")},
|
||||
{REQUIRED, config.GetPath(".osrm.turn_weight_penalties")},
|
||||
{REQUIRED, config.GetPath(".osrm.turn_duration_penalties")},
|
||||
};
|
||||
|
||||
// Connectivity matrix checksum
|
||||
std::uint32_t turns_connectivity_checksum = 0;
|
||||
for (const auto &file : tar_files)
|
||||
{
|
||||
if (boost::filesystem::exists(file.second))
|
||||
{
|
||||
readBlocks(file.second, updatable_layout);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (file.first == REQUIRED)
|
||||
{
|
||||
throw util::exception("Could not find required filed: " +
|
||||
std::get<1>(file).string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Storage::PopulateStaticData(const SharedDataIndex &index)
|
||||
{
|
||||
// read actual data into shared memory object //
|
||||
|
||||
// store the filename of the on-disk portion of the RTree
|
||||
{
|
||||
const auto file_index_path_ptr =
|
||||
layout.GetBlockPtr<char>(memory_ptr, "/common/rtree/file_index_path");
|
||||
const auto file_index_path_ptr = index.GetBlockPtr<char>("/common/rtree/file_index_path");
|
||||
// make sure we have 0 ending
|
||||
std::fill(file_index_path_ptr,
|
||||
file_index_path_ptr + layout.GetBlockSize("/common/rtree/file_index_path"),
|
||||
file_index_path_ptr + index.GetBlockSize("/common/rtree/file_index_path"),
|
||||
0);
|
||||
const auto absolute_file_index_path =
|
||||
boost::filesystem::absolute(config.GetPath(".osrm.fileIndex")).string();
|
||||
BOOST_ASSERT(static_cast<std::size_t>(layout.GetBlockSize(
|
||||
BOOST_ASSERT(static_cast<std::size_t>(index.GetBlockSize(
|
||||
"/common/rtree/file_index_path")) >= absolute_file_index_path.size());
|
||||
std::copy(
|
||||
absolute_file_index_path.begin(), absolute_file_index_path.end(), file_index_path_ptr);
|
||||
@@ -290,81 +349,50 @@ void Storage::PopulateData(const DataLayout &layout, char *memory_ptr)
|
||||
|
||||
// Name data
|
||||
{
|
||||
auto name_table = make_name_table_view(memory_ptr, layout, "/common/names");
|
||||
auto name_table = make_name_table_view(index, "/common/names");
|
||||
extractor::files::readNames(config.GetPath(".osrm.names"), name_table);
|
||||
}
|
||||
|
||||
// Turn lane data
|
||||
{
|
||||
auto turn_lane_data = make_lane_data_view(memory_ptr, layout, "/common/turn_lanes");
|
||||
auto turn_lane_data = make_lane_data_view(index, "/common/turn_lanes");
|
||||
extractor::files::readTurnLaneData(config.GetPath(".osrm.tld"), turn_lane_data);
|
||||
}
|
||||
|
||||
// Turn lane descriptions
|
||||
{
|
||||
auto views = make_turn_lane_description_views(memory_ptr, layout, "/common/turn_lanes");
|
||||
auto views = make_turn_lane_description_views(index, "/common/turn_lanes");
|
||||
extractor::files::readTurnLaneDescriptions(
|
||||
config.GetPath(".osrm.tls"), std::get<0>(views), std::get<1>(views));
|
||||
}
|
||||
|
||||
// Load edge-based nodes data
|
||||
{
|
||||
auto node_data = make_ebn_data_view(memory_ptr, layout, "/common/ebg_node_data");
|
||||
auto node_data = make_ebn_data_view(index, "/common/ebg_node_data");
|
||||
extractor::files::readNodeData(config.GetPath(".osrm.ebg_nodes"), node_data);
|
||||
}
|
||||
|
||||
// Load original edge data
|
||||
{
|
||||
auto turn_data = make_turn_data_view(memory_ptr, layout, "/common/turn_data");
|
||||
auto turn_data = make_turn_data_view(index, "/common/turn_data");
|
||||
|
||||
auto connectivity_checksum_ptr =
|
||||
layout.GetBlockPtr<std::uint32_t>(memory_ptr, "/common/connectivity_checksum");
|
||||
index.GetBlockPtr<std::uint32_t>("/common/connectivity_checksum");
|
||||
|
||||
guidance::files::readTurnData(
|
||||
config.GetPath(".osrm.edges"), turn_data, *connectivity_checksum_ptr);
|
||||
|
||||
turns_connectivity_checksum = *connectivity_checksum_ptr;
|
||||
}
|
||||
|
||||
// load compressed geometry
|
||||
{
|
||||
auto segment_data = make_segment_data_view(memory_ptr, layout, "/common/segment_data");
|
||||
extractor::files::readSegmentData(config.GetPath(".osrm.geometry"), segment_data);
|
||||
}
|
||||
|
||||
{
|
||||
const auto datasources_names_ptr =
|
||||
layout.GetBlockPtr<extractor::Datasources>(memory_ptr, "/common/data_sources_names");
|
||||
extractor::files::readDatasources(config.GetPath(".osrm.datasource_names"),
|
||||
*datasources_names_ptr);
|
||||
}
|
||||
|
||||
// Loading list of coordinates
|
||||
{
|
||||
auto views = make_nbn_data_view(memory_ptr, layout, "/common/nbn_data");
|
||||
auto views = make_nbn_data_view(index, "/common/nbn_data");
|
||||
extractor::files::readNodes(
|
||||
config.GetPath(".osrm.nbg_nodes"), std::get<0>(views), std::get<1>(views));
|
||||
}
|
||||
|
||||
// load turn weight penalties
|
||||
{
|
||||
auto turn_duration_penalties =
|
||||
make_turn_weight_view(memory_ptr, layout, "/common/turn_penalty");
|
||||
extractor::files::readTurnWeightPenalty(config.GetPath(".osrm.turn_weight_penalties"),
|
||||
turn_duration_penalties);
|
||||
}
|
||||
|
||||
// load turn duration penalties
|
||||
{
|
||||
auto turn_duration_penalties =
|
||||
make_turn_duration_view(memory_ptr, layout, "/common/turn_penalty");
|
||||
extractor::files::readTurnDurationPenalty(config.GetPath(".osrm.turn_duration_penalties"),
|
||||
turn_duration_penalties);
|
||||
}
|
||||
|
||||
// store search tree portion of rtree
|
||||
{
|
||||
auto rtree = make_search_tree_view(memory_ptr, layout, "/common/rtree");
|
||||
auto rtree = make_search_tree_view(index, "/common/rtree");
|
||||
extractor::files::readRamIndex(config.GetPath(".osrm.ramIndex"), rtree);
|
||||
}
|
||||
|
||||
@@ -372,8 +400,8 @@ void Storage::PopulateData(const DataLayout &layout, char *memory_ptr)
|
||||
std::string metric_name;
|
||||
// load profile properties
|
||||
{
|
||||
const auto profile_properties_ptr =
|
||||
layout.GetBlockPtr<extractor::ProfileProperties>(memory_ptr, "/common/properties");
|
||||
const auto profile_properties_ptr = index.GetBlockPtr<extractor::ProfileProperties>(
|
||||
"/common/properties");
|
||||
extractor::files::readProfileProperties(config.GetPath(".osrm.properties"),
|
||||
*profile_properties_ptr);
|
||||
|
||||
@@ -383,49 +411,95 @@ void Storage::PopulateData(const DataLayout &layout, char *memory_ptr)
|
||||
// Load intersection data
|
||||
{
|
||||
auto intersection_bearings_view =
|
||||
make_intersection_bearings_view(memory_ptr, layout, "/common/intersection_bearings");
|
||||
auto entry_classes = make_entry_classes_view(memory_ptr, layout, "/common/entry_classes");
|
||||
make_intersection_bearings_view(index, "/common/intersection_bearings");
|
||||
auto entry_classes = make_entry_classes_view(index, "/common/entry_classes");
|
||||
extractor::files::readIntersections(
|
||||
config.GetPath(".osrm.icd"), intersection_bearings_view, entry_classes);
|
||||
}
|
||||
|
||||
if (boost::filesystem::exists(config.GetPath(".osrm.partition")))
|
||||
{
|
||||
auto mlp = make_partition_view(index, "/mld/multilevelpartition");
|
||||
partitioner::files::readPartition(config.GetPath(".osrm.partition"), mlp);
|
||||
}
|
||||
|
||||
if (boost::filesystem::exists(config.GetPath(".osrm.cells")))
|
||||
{
|
||||
auto storage = make_cell_storage_view(index, "/mld/cellstorage");
|
||||
partitioner::files::readCells(config.GetPath(".osrm.cells"), storage);
|
||||
}
|
||||
|
||||
if (boost::filesystem::exists(config.GetPath(".osrm.cell_metrics")))
|
||||
{
|
||||
auto exclude_metrics = make_cell_metric_view(index, "/mld/metrics/" + metric_name);
|
||||
std::unordered_map<std::string, std::vector<customizer::CellMetricView>> metrics = {
|
||||
{metric_name, std::move(exclude_metrics)},
|
||||
};
|
||||
customizer::files::readCellMetrics(config.GetPath(".osrm.cell_metrics"), metrics);
|
||||
}
|
||||
|
||||
// load maneuver overrides
|
||||
{
|
||||
auto views = make_maneuver_overrides_views(index, "/common/maneuver_overrides");
|
||||
extractor::files::readManeuverOverrides(
|
||||
config.GetPath(".osrm.maneuver_overrides"), std::get<0>(views), std::get<1>(views));
|
||||
}
|
||||
}
|
||||
|
||||
void Storage::PopulateUpdatableData(const SharedDataIndex &index)
|
||||
{
|
||||
// load compressed geometry
|
||||
{
|
||||
auto segment_data = make_segment_data_view(index, "/common/segment_data");
|
||||
extractor::files::readSegmentData(config.GetPath(".osrm.geometry"), segment_data);
|
||||
}
|
||||
|
||||
{
|
||||
const auto datasources_names_ptr = index.GetBlockPtr<extractor::Datasources>(
|
||||
"/common/data_sources_names");
|
||||
extractor::files::readDatasources(config.GetPath(".osrm.datasource_names"),
|
||||
*datasources_names_ptr);
|
||||
}
|
||||
|
||||
// load turn weight penalties
|
||||
{
|
||||
auto turn_duration_penalties = make_turn_weight_view(index, "/common/turn_penalty");
|
||||
extractor::files::readTurnWeightPenalty(config.GetPath(".osrm.turn_weight_penalties"),
|
||||
turn_duration_penalties);
|
||||
}
|
||||
|
||||
// load turn duration penalties
|
||||
{
|
||||
auto turn_duration_penalties = make_turn_duration_view(index, "/common/turn_penalty");
|
||||
extractor::files::readTurnDurationPenalty(config.GetPath(".osrm.turn_duration_penalties"),
|
||||
turn_duration_penalties);
|
||||
}
|
||||
|
||||
// FIXME we only need to get the weight name
|
||||
std::string metric_name;
|
||||
// load profile properties
|
||||
{
|
||||
extractor::ProfileProperties properties;
|
||||
extractor::files::readProfileProperties(config.GetPath(".osrm.properties"), properties);
|
||||
|
||||
metric_name = properties.GetWeightName();
|
||||
}
|
||||
|
||||
if (boost::filesystem::exists(config.GetPath(".osrm.hsgr")))
|
||||
{
|
||||
const std::string metric_prefix = "/ch/metrics/" + metric_name;
|
||||
auto contracted_metric = make_contracted_metric_view(memory_ptr, layout, metric_prefix);
|
||||
auto contracted_metric = make_contracted_metric_view(index, metric_prefix);
|
||||
std::unordered_map<std::string, contractor::ContractedMetricView> metrics = {
|
||||
{metric_name, std::move(contracted_metric)}};
|
||||
|
||||
std::uint32_t graph_connectivity_checksum = 0;
|
||||
contractor::files::readGraph(
|
||||
config.GetPath(".osrm.hsgr"), metrics, graph_connectivity_checksum);
|
||||
|
||||
if (turns_connectivity_checksum != graph_connectivity_checksum)
|
||||
{
|
||||
throw util::exception(
|
||||
"Connectivity checksum " + std::to_string(graph_connectivity_checksum) + " in " +
|
||||
config.GetPath(".osrm.hsgr").string() + " does not equal to checksum " +
|
||||
std::to_string(turns_connectivity_checksum) + " in " +
|
||||
config.GetPath(".osrm.edges").string());
|
||||
}
|
||||
}
|
||||
|
||||
if (boost::filesystem::exists(config.GetPath(".osrm.partition")))
|
||||
{
|
||||
auto mlp = make_partition_view(memory_ptr, layout, "/mld/multilevelpartition");
|
||||
partitioner::files::readPartition(config.GetPath(".osrm.partition"), mlp);
|
||||
}
|
||||
|
||||
if (boost::filesystem::exists(config.GetPath(".osrm.cells")))
|
||||
{
|
||||
auto storage = make_cell_storage_view(memory_ptr, layout, "/mld/cellstorage");
|
||||
partitioner::files::readCells(config.GetPath(".osrm.cells"), storage);
|
||||
}
|
||||
|
||||
if (boost::filesystem::exists(config.GetPath(".osrm.cell_metrics")))
|
||||
{
|
||||
auto exclude_metrics =
|
||||
make_cell_metric_view(memory_ptr, layout, "/mld/metrics/" + metric_name);
|
||||
auto exclude_metrics = make_cell_metric_view(index, "/mld/metrics/" + metric_name);
|
||||
std::unordered_map<std::string, std::vector<customizer::CellMetricView>> metrics = {
|
||||
{metric_name, std::move(exclude_metrics)},
|
||||
};
|
||||
@@ -434,27 +508,10 @@ void Storage::PopulateData(const DataLayout &layout, char *memory_ptr)
|
||||
|
||||
if (boost::filesystem::exists(config.GetPath(".osrm.mldgr")))
|
||||
{
|
||||
auto graph_view = make_multi_level_graph_view(memory_ptr, layout, "/mld/multilevelgraph");
|
||||
auto graph_view = make_multi_level_graph_view(index, "/mld/multilevelgraph");
|
||||
std::uint32_t graph_connectivity_checksum = 0;
|
||||
partitioner::files::readGraph(
|
||||
config.GetPath(".osrm.mldgr"), graph_view, graph_connectivity_checksum);
|
||||
|
||||
if (turns_connectivity_checksum != graph_connectivity_checksum)
|
||||
{
|
||||
throw util::exception(
|
||||
"Connectivity checksum " + std::to_string(graph_connectivity_checksum) + " in " +
|
||||
config.GetPath(".osrm.mldgr").string() + " does not equal to checksum " +
|
||||
std::to_string(turns_connectivity_checksum) + " in " +
|
||||
config.GetPath(".osrm.edges").string());
|
||||
}
|
||||
}
|
||||
|
||||
// load maneuver overrides
|
||||
{
|
||||
auto views =
|
||||
make_maneuver_overrides_views(memory_ptr, layout, "/common/maneuver_overrides");
|
||||
extractor::files::readManeuverOverrides(
|
||||
config.GetPath(".osrm.maneuver_overrides"), std::get<0>(views), std::get<1>(views));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user