diff options
| author | Dan Engelbrecht <[email protected]> | 2024-08-30 11:26:42 +0200 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2024-08-30 11:26:42 +0200 |
| commit | cbb9ed149517cf781bf21bff4650d7d01bd6d567 (patch) | |
| tree | a185fe2a84cd6681caae7a71bb72d398421f97b6 /src/zenstore/blockstore.cpp | |
| parent | zenserver process launch/termination improvements (#138) (diff) | |
| download | zen-cbb9ed149517cf781bf21bff4650d7d01bd6d567.tar.xz zen-cbb9ed149517cf781bf21bff4650d7d01bd6d567.zip | |
meta info store (#75)
- Feature: Added option `--gc-cache-attachment-store` which caches referenced attachments in cache records on disk for faster GC - default is `false`
- Feature: Added option `--gc-projectstore-attachment-store` which caches referenced attachments in project store oplogs on disk for faster GC - default is `false`
Diffstat (limited to 'src/zenstore/blockstore.cpp')
| -rw-r--r-- | src/zenstore/blockstore.cpp | 154 |
1 files changed, 147 insertions, 7 deletions
diff --git a/src/zenstore/blockstore.cpp b/src/zenstore/blockstore.cpp index 70ddcedaf..287a3f7fa 100644 --- a/src/zenstore/blockstore.cpp +++ b/src/zenstore/blockstore.cpp @@ -90,6 +90,7 @@ BlockStoreFile::Create(uint64_t InitialSize) RetriesLeft--; return true; }); + RemoveMeta(); void* FileHandle = m_File.Handle(); @@ -99,15 +100,26 @@ BlockStoreFile::Create(uint64_t InitialSize) } uint64_t -BlockStoreFile::FileSize() +BlockStoreFile::FileSize() const { - return m_CachedFileSize == 0 ? m_File.FileSize() : m_CachedFileSize; + if (m_CachedFileSize == 0) + { + std::error_code Ec; + uint64_t Size = m_File.FileSize(Ec); + if (Ec) + { + return 0; + } + return Size; + } + return m_CachedFileSize; } void BlockStoreFile::MarkAsDeleteOnClose() { m_IoBuffer.SetDeleteOnClose(true); + RemoveMeta(); } IoBuffer @@ -157,6 +169,90 @@ BlockStoreFile::IsOpen() const return !!m_IoBuffer; } +bool +BlockStoreFile::SetMetaData(const IoBuffer& Payload) +{ + if (!Payload) + { + RemoveMeta(); + return true; + } + const std::filesystem::path MetaPath = GetMetaPath(); + std::error_code Ec; + TemporaryFile::SafeWriteFile(MetaPath, Payload.GetView(), Ec); + if (Ec) + { + ZEN_WARN("Unable to set meta data for block '{}' at meta path: '{}'. Reason: '{}'", m_Path, MetaPath, Ec.message()); + return false; + } + return true; +} + +static bool +IsMetaDataValid(const std::filesystem::path& BlockPath, const std::filesystem::path& MetaPath) +{ + std::error_code Ec; + std::filesystem::file_time_type MetaWriteTime = std::filesystem::last_write_time(MetaPath, Ec); + if (Ec) + { + return false; + } + std::filesystem::file_time_type BlockWriteTime = std::filesystem::last_write_time(BlockPath, Ec); + if (Ec) + { + return false; + } + if (MetaWriteTime < BlockWriteTime) + { + std::filesystem::remove(MetaPath, Ec); + return false; + } + return true; +} + +IoBuffer +BlockStoreFile::GetMetaData() const +{ + const std::filesystem::path MetaPath = GetMetaPath(); + if (IsMetaDataValid(m_Path, MetaPath)) + { + return IoBufferBuilder::MakeFromFile(MetaPath); + } + return {}; +} + +uint64_t +BlockStoreFile::MetaSize() const +{ + const std::filesystem::path MetaPath = GetMetaPath(); + if (IsMetaDataValid(m_Path, MetaPath)) + { + std::error_code DummyEc; + if (uint64_t Size = std::filesystem::file_size(MetaPath, DummyEc); !DummyEc) + { + return Size; + } + } + return 0; +} + +void +BlockStoreFile::RemoveMeta() +{ + std::filesystem::path MetaPath = GetMetaPath(); + std::error_code DummyEc; + std::filesystem::remove(MetaPath, DummyEc); +} + +std::filesystem::path +BlockStoreFile::GetMetaPath() const +{ + std::filesystem::path MetaPath(m_Path); + return MetaPath.replace_extension(".meta"); +} + +//////////////////////////////////////////////////////// + constexpr uint64_t DefaultIterateSmallChunkWindowSize = 2 * 1024 * 1024; constexpr uint64_t IterateSmallChunkMaxGapSize = 4 * 1024; @@ -215,7 +311,7 @@ BlockStore::Initialize(const std::filesystem::path& BlocksBasePath, uint64_t Max } Ref<BlockStoreFile> BlockFile{new BlockStoreFile(Path)}; BlockFile->Open(); - m_TotalSize.fetch_add(BlockFile->FileSize(), std::memory_order::relaxed); + m_TotalSize.fetch_add(BlockFile->TotalSize(), std::memory_order::relaxed); m_ChunkBlocks[BlockIndex] = BlockFile; FoundBlocks[BlockIndex] = BlockFile->FileSize(); if (BlockIndex >= NextBlockIndex) @@ -283,7 +379,7 @@ BlockStore::SyncExistingBlocksOnDisk(const BlockIndexSet& KnownLocations) std::filesystem::path BlockPath = GetBlockPath(m_BlocksBasePath, BlockIndex); if (m_ChunkBlocks[BlockIndex]) { - m_TotalSize.fetch_sub(m_ChunkBlocks[BlockIndex]->FileSize(), std::memory_order::relaxed); + m_TotalSize.fetch_sub(m_ChunkBlocks[BlockIndex]->TotalSize(), std::memory_order::relaxed); m_ChunkBlocks[BlockIndex]->MarkAsDeleteOnClose(); } m_ChunkBlocks.erase(BlockIndex); @@ -781,6 +877,7 @@ BlockStore::ReclaimSpace(const ReclaimSnapshotState& Snapshot, { ZEN_DEBUG("dropping incomplete cas block store file '{}'", NewBlockFile->GetPath()); m_TotalSize.fetch_sub(NewBlockFile->FileSize(), std::memory_order::relaxed); + ZEN_ASSERT_SLOW(NewBlockFile->MetaSize() == 0); NewBlockFile->MarkAsDeleteOnClose(); } }); @@ -833,7 +930,7 @@ BlockStore::ReclaimSpace(const ReclaimSnapshotState& Snapshot, ZEN_DEBUG("marking cas block store file '{}' for delete, block #{}", OldBlockFile->GetPath(), BlockIndex); ZEN_ASSERT(m_ChunkBlocks[BlockIndex] == OldBlockFile); m_ChunkBlocks.erase(BlockIndex); - m_TotalSize.fetch_sub(OldBlockFile->FileSize(), std::memory_order::relaxed); + m_TotalSize.fetch_sub(OldBlockFile->TotalSize(), std::memory_order::relaxed); OldBlockFile->MarkAsDeleteOnClose(); } continue; @@ -1003,7 +1100,7 @@ BlockStore::ReclaimSpace(const ReclaimSnapshotState& Snapshot, ZEN_DEBUG("marking cas block store file '{}' for delete, block #{}", OldBlockFile->GetPath(), BlockIndex); ZEN_ASSERT(m_ChunkBlocks[BlockIndex] == OldBlockFile); m_ChunkBlocks.erase(BlockIndex); - m_TotalSize.fetch_sub(OldBlockFile->FileSize(), std::memory_order::relaxed); + m_TotalSize.fetch_sub(OldBlockFile->TotalSize(), std::memory_order::relaxed); OldBlockFile->MarkAsDeleteOnClose(); } } @@ -1500,9 +1597,10 @@ BlockStore::CompactBlocks(const BlockStoreCompactState& CompactState, LogPrefix, OldBlockFile->GetPath().filename(), NiceBytes(OldBlockSize)); + m_TotalSize.fetch_sub(OldBlockSize); + m_TotalSize.fetch_sub(OldBlockFile->MetaSize()); OldBlockFile->MarkAsDeleteOnClose(); m_ChunkBlocks.erase(BlockIndex); - m_TotalSize.fetch_sub(OldBlockSize); RemovedSize += OldBlockSize; } return true; @@ -1544,6 +1642,48 @@ BlockStore::GetBlockPath(const std::filesystem::path& BlocksBasePath, const uint return Path.ToPath(); } +bool +BlockStore::IsWriting(uint32_t BlockIndex) const +{ + RwLock::SharedLockScope _(m_InsertLock); + if (std::find(m_ActiveWriteBlocks.begin(), m_ActiveWriteBlocks.end(), BlockIndex) != m_ActiveWriteBlocks.end()) + { + return true; + } + if (BlockIndex == m_WriteBlockIndex.load() && m_WriteBlock) + { + return true; + } + return false; +} + +void +BlockStore::SetMetaData(uint32_t BlockIndex, const IoBuffer& Payload) +{ + RwLock::ExclusiveLockScope _(m_InsertLock); + if (auto It = m_ChunkBlocks.find(BlockIndex); It != m_ChunkBlocks.end() && It->second) + { + uint64_t OldMetaSize = It->second->MetaSize(); + if (It->second->SetMetaData(Payload)) + { + uint64_t NewMetaSize = It->second->MetaSize(); + m_TotalSize += NewMetaSize; + m_TotalSize -= OldMetaSize; + } + } +} + +IoBuffer +BlockStore::GetMetaData(uint32_t BlockIndex) const +{ + RwLock::SharedLockScope _(m_InsertLock); + if (auto It = m_ChunkBlocks.find(BlockIndex); It != m_ChunkBlocks.end() && It->second) + { + return It->second->GetMetaData(); + } + return {}; +} + #if ZEN_WITH_TESTS TEST_CASE("blockstore.blockstoredisklocation") |