mmap tarfiles directly when mmapping is enabled
This commit is contained in:
committed by
Daniel Paz-Soldan
parent
cb5d596a5a
commit
2b18954cb9
@@ -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};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ®ion : 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 ®ion = 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 ®ion = 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 ®ion = GetBlockRegion(name);
|
||||
return region.layout.GetBlockEntries(name);
|
||||
return region.layout->GetBlockEntries(name);
|
||||
}
|
||||
|
||||
std::size_t GetBlockSize(const std::string &name) const
|
||||
{
|
||||
const auto ®ion = GetBlockRegion(name);
|
||||
return region.layout.GetBlockSize(name);
|
||||
return region.layout->GetBlockSize(name);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user