mmap tarfiles directly when mmapping is enabled

This commit is contained in:
Daniel Patterson
2018-10-21 21:22:41 -07:00
committed by Daniel Paz-Soldan
parent cb5d596a5a
commit 2b18954cb9
14 changed files with 359 additions and 231 deletions
+8 -3
View File
@@ -16,10 +16,15 @@ struct Block
{
std::uint64_t num_entries;
std::uint64_t byte_size;
std::uint64_t offset;
Block() : num_entries(0), byte_size(0) {}
Block() : num_entries(0), byte_size(0), offset(0) {}
Block(std::uint64_t num_entries, std::uint64_t byte_size, std::uint64_t offset)
: num_entries(num_entries), byte_size(byte_size), offset(offset)
{
}
Block(std::uint64_t num_entries, std::uint64_t byte_size)
: num_entries(num_entries), byte_size(byte_size)
: num_entries(num_entries), byte_size(byte_size), offset(0)
{
}
};
@@ -29,7 +34,7 @@ using NamedBlock = std::tuple<std::string, Block>;
template <typename T> Block make_block(uint64_t num_entries)
{
static_assert(sizeof(T) % alignof(T) == 0, "aligned T* can't be used as an array pointer");
return Block{num_entries, sizeof(T) * num_entries};
return Block{num_entries, sizeof(T) * num_entries, 0};
}
}
}
+10 -7
View File
@@ -97,7 +97,7 @@ void writeBoolVector(tar::FileWriter &writer, const std::string &name, const Vec
boost::make_function_input_iterator(encode_function, boost::infinite()),
number_of_blocks);
}
}
} // namespace detail
/* All vector formats here use the same on-disk format.
* This is important because we want to be able to write from a vector
@@ -273,14 +273,17 @@ template <typename K, typename V> void write(io::BufferWriter &writer, const std
}
}
inline void read(io::BufferReader &reader, DataLayout &layout) { read(reader, layout.blocks); }
inline void write(io::BufferWriter &writer, const DataLayout &layout)
inline void read(io::BufferReader &reader, std::unique_ptr<BaseDataLayout> &layout)
{
write(writer, layout.blocks);
}
}
read(reader, layout->blocks);
}
inline void write(io::BufferWriter &writer, const std::unique_ptr<BaseDataLayout> &layout)
{
write(writer, layout->blocks);
}
} // namespace serialization
} // namespace storage
} // namespace osrm
#endif
+10 -10
View File
@@ -20,7 +20,7 @@ class SharedDataIndex
struct AllocatedRegion
{
char *memory_ptr;
DataLayout layout;
std::unique_ptr<BaseDataLayout> layout;
};
SharedDataIndex() = default;
@@ -29,10 +29,10 @@ class SharedDataIndex
// Build mapping from block name to region
for (auto index : util::irange<std::uint32_t>(0, regions.size()))
{
regions[index].layout.List("",
boost::make_function_output_iterator([&](const auto &name) {
block_to_region[name] = index;
}));
regions[index].layout->List("",
boost::make_function_output_iterator([&](const auto &name) {
block_to_region[name] = index;
}));
}
}
@@ -40,32 +40,32 @@ class SharedDataIndex
{
for (const auto &region : regions)
{
region.layout.List(name_prefix, out);
region.layout->List(name_prefix, out);
}
}
template <typename T> auto GetBlockPtr(const std::string &name) const
{
const auto &region = GetBlockRegion(name);
return region.layout.GetBlockPtr<T>(region.memory_ptr, name);
return reinterpret_cast<T *>(region.layout->GetBlockPtr(region.memory_ptr, name));
}
template <typename T> auto GetBlockPtr(const std::string &name)
{
const auto &region = GetBlockRegion(name);
return region.layout.GetBlockPtr<T>(region.memory_ptr, name);
return reinterpret_cast<T *>(region.layout->GetBlockPtr(region.memory_ptr, name));
}
std::size_t GetBlockEntries(const std::string &name) const
{
const auto &region = GetBlockRegion(name);
return region.layout.GetBlockEntries(name);
return region.layout->GetBlockEntries(name);
}
std::size_t GetBlockSize(const std::string &name) const
{
const auto &region = GetBlockRegion(name);
return region.layout.GetBlockSize(name);
return region.layout->GetBlockSize(name);
}
private:
+120 -36
View File
@@ -20,12 +20,12 @@ namespace osrm
namespace storage
{
class DataLayout;
class BaseDataLayout;
namespace serialization
{
inline void read(io::BufferReader &reader, DataLayout &layout);
inline void read(io::BufferReader &reader, std::unique_ptr<BaseDataLayout> &layout);
inline void write(io::BufferWriter &writer, const DataLayout &layout);
inline void write(io::BufferWriter &writer, const std::unique_ptr<BaseDataLayout> &layout);
} // namespace serialization
namespace detail
@@ -54,43 +54,20 @@ inline std::string trimName(const std::string &name_prefix, const std::string &n
}
} // namespace detail
class DataLayout
class BaseDataLayout
{
public:
DataLayout() : blocks{} {}
virtual ~BaseDataLayout() = default;
inline void SetBlock(const std::string &name, Block block) { blocks[name] = std::move(block); }
virtual inline void SetBlock(const std::string &name, Block block) = 0;
inline uint64_t GetBlockEntries(const std::string &name) const
{
return GetBlock(name).num_entries;
}
virtual inline uint64_t GetBlockEntries(const std::string &name) const = 0;
inline uint64_t GetBlockSize(const std::string &name) const { return GetBlock(name).byte_size; }
virtual inline uint64_t GetBlockSize(const std::string &name) const = 0;
inline bool HasBlock(const std::string &name) const
{
return blocks.find(name) != blocks.end();
}
virtual inline bool HasBlock(const std::string &name) const = 0;
inline uint64_t GetSizeOfLayout() const
{
uint64_t result = 0;
for (const auto &name_and_block : blocks)
{
result += GetBlockSize(name_and_block.first) + BLOCK_ALIGNMENT;
}
return result;
}
template <typename T> inline T *GetBlockPtr(char *shared_memory, const std::string &name) const
{
static_assert(BLOCK_ALIGNMENT % std::alignment_of<T>::value == 0,
"Datatype does not fit alignment constraints.");
char *ptr = (char *)GetAlignedBlockPtr(shared_memory, name);
return (T *)ptr;
}
virtual inline uint64_t GetSizeOfLayout() const = 0;
// Depending on the name prefix this function either lists all blocks with the same prefix
// or all entries in the sub-directory.
@@ -115,9 +92,59 @@ class DataLayout
}
}
virtual inline void *GetBlockPtr(char *shared_memory, const std::string &name) const = 0;
std::map<std::string, Block> blocks;
};
class DataLayout final : public BaseDataLayout
{
public:
inline void SetBlock(const std::string &name, Block block) override final
{
blocks[name] = std::move(block);
}
inline uint64_t GetBlockEntries(const std::string &name) const override final
{
return GetBlock(name).num_entries;
}
inline uint64_t GetBlockSize(const std::string &name) const override final
{
return GetBlock(name).byte_size;
}
inline bool HasBlock(const std::string &name) const override final
{
return blocks.find(name) != blocks.end();
}
inline uint64_t GetSizeOfLayout() const override final
{
uint64_t result = 0;
for (const auto &name_and_block : blocks)
{
result += GetBlockSize(name_and_block.first) + BLOCK_ALIGNMENT;
}
return result;
}
inline void *GetBlockPtr(char *shared_memory, const std::string &name) const override final
{
// TODO: re-enable this alignment checking somehow
// static_assert(BLOCK_ALIGNMENT % std::alignment_of<T>::value == 0,
// "Datatype does not fit alignment constraints.");
char *ptr = (char *)GetAlignedBlockPtr(shared_memory, name);
return ptr;
}
private:
friend void serialization::read(io::BufferReader &reader, DataLayout &layout);
friend void serialization::write(io::BufferWriter &writer, const DataLayout &layout);
friend void serialization::read(io::BufferReader &reader,
std::unique_ptr<BaseDataLayout> &layout);
friend void serialization::write(io::BufferWriter &writer,
const std::unique_ptr<BaseDataLayout> &layout);
const Block &GetBlock(const std::string &name) const
{
@@ -157,7 +184,64 @@ class DataLayout
}
static constexpr std::size_t BLOCK_ALIGNMENT = 64;
std::map<std::string, Block> blocks;
};
class TarDataLayout final : public BaseDataLayout
{
public:
inline void SetBlock(const std::string &name, Block block) override final
{
blocks[name] = std::move(block);
}
inline uint64_t GetBlockEntries(const std::string &name) const override final
{
return GetBlock(name).num_entries;
}
inline uint64_t GetBlockSize(const std::string &name) const override final
{
return GetBlock(name).byte_size;
}
inline bool HasBlock(const std::string &name) const override final
{
return blocks.find(name) != blocks.end();
}
inline uint64_t GetSizeOfLayout() const override final
{
uint64_t result = 0;
for (const auto &name_and_block : blocks)
{
result += GetBlockSize(name_and_block.first);
}
return result;
}
inline void *GetBlockPtr(char *memory_ptr, const std::string &name) const override final
{
auto offset = GetBlock(name).offset;
const auto offset_memory = memory_ptr + offset;
return offset_memory;
}
private:
friend void serialization::read(io::BufferReader &reader,
std::unique_ptr<BaseDataLayout> &layout);
friend void serialization::write(io::BufferWriter &writer,
const std::unique_ptr<BaseDataLayout> &layout);
const Block &GetBlock(const std::string &name) const
{
auto iter = blocks.find(name);
if (iter == blocks.end())
{
throw util::exception("Could not find block " + name);
}
return iter->second;
}
};
struct SharedRegion
+7 -3
View File
@@ -46,11 +46,15 @@ class Storage
Storage(StorageConfig config);
int Run(int max_wait, const std::string &name, bool only_metric);
void PopulateStaticLayout(DataLayout &layout);
void PopulateUpdatableLayout(DataLayout &layout);
void PopulateStaticData(const SharedDataIndex &index);
void PopulateUpdatableData(const SharedDataIndex &index);
void PopulateLayout(std::unique_ptr<storage::BaseDataLayout> &layout,
std::vector<std::pair<bool, boost::filesystem::path>> files);
std::string PopulateLayoutWithRTree(std::unique_ptr<storage::BaseDataLayout> &layout);
void readBlocks(const boost::filesystem::path &path,
std::unique_ptr<storage::BaseDataLayout> &layout);
std::vector<std::pair<bool, boost::filesystem::path>> GetUpdatableFiles();
std::vector<std::pair<bool, boost::filesystem::path>> GetStaticFiles();
private:
StorageConfig config;