mmap tarfiles directly when mmapping is enabled, instead of copying data into separate mmapped block

Co-authored-by: Kajari Ghosh <ghoshkaj@gmail.com>
This commit is contained in:
Daniel Patterson
2018-10-26 23:48:51 -07:00
parent d80318f8ea
commit 2f9cb44368
14 changed files with 309 additions and 219 deletions
+37 -32
View File
@@ -1,5 +1,6 @@
#include "engine/datafacade/mmap_memory_allocator.hpp"
#include "storage/block.hpp"
#include "storage/io.hpp"
#include "storage/serialization.hpp"
#include "storage/storage.hpp"
@@ -7,7 +8,7 @@
#include "util/log.hpp"
#include "util/mmap_file.hpp"
#include "boost/assert.hpp"
#include <boost/assert.hpp>
namespace osrm
{
@@ -16,46 +17,50 @@ namespace engine
namespace datafacade
{
MMapMemoryAllocator::MMapMemoryAllocator(const storage::StorageConfig &config,
const boost::filesystem::path &memory_file)
MMapMemoryAllocator::MMapMemoryAllocator(const storage::StorageConfig &config)
{
storage::Storage storage(config);
std::vector<storage::SharedDataIndex::AllocatedRegion> allocated_regions;
if (!boost::filesystem::exists(memory_file))
{
storage::DataLayout initial_layout;
storage.PopulateStaticLayout(initial_layout);
storage.PopulateUpdatableLayout(initial_layout);
std::unique_ptr<storage::BaseDataLayout> fake_layout =
std::make_unique<storage::TarDataLayout>();
auto data_size = initial_layout.GetSizeOfLayout();
// Convert the boost::filesystem::path object into a plain string
// that's stored as a member of this allocator object
rtree_filename = storage.PopulateLayoutWithRTree(*fake_layout);
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);
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);
// Now, we add one more AllocatedRegion, with it's start address as the start
// of the rtree_filename string we've saved. In the fake_layout, we've
// stated that the data is at offset 0, which is where the string starts
// at it's own memory address.
// The syntax &(rtree_filename[0]) gets the memory address of the first char.
// We can't use the convenient `.data()` or `.c_str()` methods, because
// prior to C++17 (which we're not using), those return a `const char *`,
// which isn't compatible with the `char *` that AllocatedRegion expects
// for it's memory_ptr
allocated_regions.push_back({&(rtree_filename[0]), std::move(fake_layout)});
}
else
auto files = storage.GetStaticFiles();
auto updatable_files = storage.GetUpdatableFiles();
files.insert(files.end(), updatable_files.begin(), updatable_files.end());
for (const auto &file : files)
{
mapped_memory = util::mmapFile<char>(memory_file, mapped_memory_file);
storage::DataLayout layout;
storage::io::BufferReader reader(mapped_memory.data(), mapped_memory.size());
storage::serialization::read(reader, layout);
auto layout_size = reader.GetPosition();
index = storage::SharedDataIndex({{mapped_memory.data() + layout_size, std::move(layout)}});
if (boost::filesystem::exists(file.second))
{
std::unique_ptr<storage::BaseDataLayout> layout =
std::make_unique<storage::TarDataLayout>();
boost::iostreams::mapped_file mapped_memory_file;
util::mmapFile<char>(file.second, mapped_memory_file);
mapped_memory_files.push_back(std::move(mapped_memory_file));
storage::populateLayoutFromFile(file.second, *layout);
allocated_regions.push_back({mapped_memory_file.data(), std::move(layout)});
}
}
index = storage::SharedDataIndex{std::move(allocated_regions)};
}
MMapMemoryAllocator::~MMapMemoryAllocator() {}
@@ -15,14 +15,20 @@ ProcessMemoryAllocator::ProcessMemoryAllocator(const storage::StorageConfig &con
storage::Storage storage(config);
// Calculate the layout/size of the memory block
storage::DataLayout layout;
storage.PopulateStaticLayout(layout);
storage.PopulateUpdatableLayout(layout);
auto static_files = storage.GetStaticFiles();
auto updatable_files = storage.GetUpdatableFiles();
std::unique_ptr<storage::BaseDataLayout> layout =
std::make_unique<storage::ContiguousDataLayout>();
storage.PopulateLayoutWithRTree(*layout);
storage.PopulateLayout(*layout, static_files);
storage.PopulateLayout(*layout, updatable_files);
// Allocate the memory block, then load data from files into it
internal_memory = std::make_unique<char[]>(layout.GetSizeOfLayout());
internal_memory = std::make_unique<char[]>(layout->GetSizeOfLayout());
index = storage::SharedDataIndex({{internal_memory.get(), std::move(layout)}});
std::vector<storage::SharedDataIndex::AllocatedRegion> regions;
regions.push_back({internal_memory.get(), std::move(layout)});
index = {std::move(regions)};
storage.PopulateStaticData(index);
storage.PopulateUpdatableData(index);
@@ -25,8 +25,9 @@ SharedMemoryAllocator::SharedMemoryAllocator(
auto mem = storage::makeSharedMemory(shm_key);
storage::io::BufferReader reader(reinterpret_cast<char *>(mem->Ptr()), mem->Size());
storage::DataLayout layout;
storage::serialization::read(reader, layout);
std::unique_ptr<storage::BaseDataLayout> layout =
std::make_unique<storage::ContiguousDataLayout>();
storage::serialization::read(reader, *layout);
auto layout_size = reader.GetPosition();
regions.push_back({reinterpret_cast<char *>(mem->Ptr()) + layout_size, std::move(layout)});