diff options
| author | Dan Engelbrecht <[email protected]> | 2023-10-03 13:31:02 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-10-03 13:31:02 +0200 |
| commit | 68a72b68592c416969bd36f413eb2b2762b9fcff (patch) | |
| tree | 9a5fc28eb9040f010c92f86a1745f9418dfc91ca /src/zenstore/blockstore.cpp | |
| parent | clean up date formatting (#440) (diff) | |
| download | zen-68a72b68592c416969bd36f413eb2b2762b9fcff.tar.xz zen-68a72b68592c416969bd36f413eb2b2762b9fcff.zip | |
faster accesstime save restore (#439)
- Improvement: Reduce time a cache bucket is locked for write when flushing/garbage collecting
- Change format for faster read/write and reduced size on disk
- Don't lock index while writing manifest to disk
- Skip garbage collect if we are currently in a Flush operation
- BlockStore::Flush no longer terminates currently writing block
- Garbage collect references to currently writing block but keep the block as new data may be added
- Fix BlockStore::Prune used disk space calculation
- Don't materialize data in filecas when we just need the size
Diffstat (limited to 'src/zenstore/blockstore.cpp')
| -rw-r--r-- | src/zenstore/blockstore.cpp | 84 |
1 files changed, 45 insertions, 39 deletions
diff --git a/src/zenstore/blockstore.cpp b/src/zenstore/blockstore.cpp index b5ed17fc6..f99b0bc4a 100644 --- a/src/zenstore/blockstore.cpp +++ b/src/zenstore/blockstore.cpp @@ -233,7 +233,6 @@ BlockStore::Prune(const std::vector<BlockStoreLocation>& KnownLocations) if (!KnownBlocks.contains(BlockIndex)) { Ref<BlockStoreFile> BlockFile = m_ChunkBlocks[BlockIndex]; - m_TotalSize.fetch_add(BlockFile->FileSize(), std::memory_order::relaxed); BlocksToDelete.push_back(BlockIndex); } } @@ -242,6 +241,7 @@ BlockStore::Prune(const std::vector<BlockStoreLocation>& KnownLocations) { // Clear out unused blocks Ref<BlockStoreFile> BlockFile = m_ChunkBlocks[BlockIndex]; + m_TotalSize.fetch_sub(BlockFile->FileSize(), std::memory_order::relaxed); m_ChunkBlocks.erase(BlockIndex); ZEN_DEBUG("marking block store file '{}' for delete, block #{}", BlockFile->GetPath(), BlockIndex); BlockFile->MarkAsDeleteOnClose(); @@ -354,22 +354,31 @@ BlockStore::TryGetChunk(const BlockStoreLocation& Location) const } void -BlockStore::Flush() +BlockStore::Flush(bool ForceNewBlock) { ZEN_TRACE_CPU("BlockStore::Flush"); - RwLock::ExclusiveLockScope _(m_InsertLock); - if (m_CurrentInsertOffset > 0) + if (ForceNewBlock) { - uint32_t WriteBlockIndex = m_WriteBlockIndex.load(std::memory_order_acquire); - WriteBlockIndex = (WriteBlockIndex + 1) & (m_MaxBlockCount - 1); - if (m_WriteBlock) + RwLock::ExclusiveLockScope _(m_InsertLock); + if (m_CurrentInsertOffset > 0) { - m_WriteBlock->Flush(); + uint32_t WriteBlockIndex = m_WriteBlockIndex.load(std::memory_order_acquire); + WriteBlockIndex = (WriteBlockIndex + 1) & (m_MaxBlockCount - 1); + if (m_WriteBlock) + { + m_WriteBlock->Flush(); + } + m_WriteBlock = nullptr; + m_WriteBlockIndex.store(WriteBlockIndex, std::memory_order_release); + m_CurrentInsertOffset = 0; } - m_WriteBlock = nullptr; - m_WriteBlockIndex.store(WriteBlockIndex, std::memory_order_release); - m_CurrentInsertOffset = 0; + return; + } + RwLock::SharedLockScope _(m_InsertLock); + if (m_WriteBlock) + { + m_WriteBlock->Flush(); } } @@ -449,11 +458,6 @@ BlockStore::ReclaimSpace(const ReclaimSnapshotState& Snapshot, { const BlockStoreLocation& Location = ChunkLocations[Index]; OldTotalSize += Location.Size; - if (Snapshot.m_ActiveWriteBlocks.contains(Location.BlockIndex)) - { - continue; - } - auto BlockIndexPtr = BlockIndexToChunkMapIndex.find(Location.BlockIndex); size_t ChunkMapIndex = 0; if (BlockIndexPtr == BlockIndexToChunkMapIndex.end()) @@ -524,9 +528,12 @@ BlockStore::ReclaimSpace(const ReclaimSnapshotState& Snapshot, uint32_t NewBlockIndex = 0; for (uint32_t BlockIndex : BlocksToReWrite) { + bool IsActiveWriteBlock = Snapshot.m_ActiveWriteBlocks.contains(BlockIndex); + const size_t ChunkMapIndex = BlockIndexToChunkMapIndex[BlockIndex]; Ref<BlockStoreFile> OldBlockFile; + if (!IsActiveWriteBlock) { RwLock::SharedLockScope _i(m_InsertLock); Stopwatch Timer; @@ -553,6 +560,7 @@ BlockStore::ReclaimSpace(const ReclaimSnapshotState& Snapshot, } ChangeCallback({}, DeleteMap); DeletedCount += DeleteMap.size(); + if (OldBlockFile) { RwLock::ExclusiveLockScope _i(m_InsertLock); Stopwatch Timer; @@ -561,18 +569,15 @@ BlockStore::ReclaimSpace(const ReclaimSnapshotState& Snapshot, ReadBlockTimeUs += ElapsedUs; ReadBlockLongestTimeUs = std::max(ElapsedUs, ReadBlockLongestTimeUs); }); - if (OldBlockFile) - { - 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); - OldBlockFile->MarkAsDeleteOnClose(); - } + 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); + OldBlockFile->MarkAsDeleteOnClose(); } continue; } - else if (!OldBlockFile) + else if (!OldBlockFile && !IsActiveWriteBlock) { // If the block file pointed to does not exist, move any keep chunk them to deleted list ZEN_ERROR("Expected to find block {} in {} - this should never happen, marking {} entries as deleted.", @@ -585,6 +590,7 @@ BlockStore::ReclaimSpace(const ReclaimSnapshotState& Snapshot, } MovedChunksArray MovedChunks; + if (OldBlockFile) { ZEN_TRACE_CPU("BlockStore::ReclaimSpace::MoveBlock"); std::vector<uint8_t> Chunk; @@ -689,9 +695,11 @@ BlockStore::ReclaimSpace(const ReclaimSnapshotState& Snapshot, } ChangeCallback(MovedChunks, DeleteMap); - MovedCount += KeepMap.size(); + MovedCount += MovedChunks.size(); DeletedCount += DeleteMap.size(); MovedChunks.clear(); + + if (OldBlockFile) { RwLock::ExclusiveLockScope __(m_InsertLock); Stopwatch Timer; @@ -700,14 +708,12 @@ BlockStore::ReclaimSpace(const ReclaimSnapshotState& Snapshot, ReadBlockTimeUs += ElapsedUs; ReadBlockLongestTimeUs = std::max(ElapsedUs, ReadBlockLongestTimeUs); }); - if (OldBlockFile) - { - 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); - OldBlockFile->MarkAsDeleteOnClose(); - } + + 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); + OldBlockFile->MarkAsDeleteOnClose(); } } if (NewBlockFile) @@ -1117,7 +1123,7 @@ TEST_CASE("blockstore.clean.stray.blocks") CHECK(GetDirectoryContent(RootDirectory / "store", true, false).size() == 1); } -TEST_CASE("blockstore.flush.forces.new.block") +TEST_CASE("blockstore.flush.force.new.block") { using namespace blockstore::impl; @@ -1129,10 +1135,10 @@ TEST_CASE("blockstore.flush.forces.new.block") std::string FirstChunkData = "This is the data of the first chunk that we will write"; WriteStringAsChunk(Store, FirstChunkData, 4); - Store.Flush(); + Store.Flush(/*ForceNewBlock*/ true); std::string SecondChunkData = "This is the data for the second chunk that we will write"; WriteStringAsChunk(Store, SecondChunkData, 4); - Store.Flush(); + Store.Flush(/*ForceNewBlock*/ true); std::string ThirdChunkData = "This is a much longer string that will not fit in the first block so it should be placed in the second block"; WriteStringAsChunk(Store, ThirdChunkData, 4); @@ -1157,7 +1163,7 @@ TEST_CASE("blockstore.iterate.chunks") std::string SecondChunkData = "This is the data for the second chunk that we will write"; BlockStoreLocation SecondChunkLocation = WriteStringAsChunk(Store, SecondChunkData, 4); - Store.Flush(); + Store.Flush(/*ForceNewBlock*/ false); std::string VeryLargeChunk(ScrubSmallChunkWindowSize * 2, 'L'); BlockStoreLocation VeryLargeChunkLocation = WriteStringAsChunk(Store, VeryLargeChunk, 4); @@ -1267,7 +1273,7 @@ TEST_CASE("blockstore.reclaim.space") ChunksToKeep.push_back(ChunkIndex); } - Store.Flush(); + Store.Flush(/*ForceNewBlock*/ false); BlockStore::ReclaimSnapshotState State1 = Store.GetReclaimSnapshotState(); Store.ReclaimSpace(State1, ChunkLocations, ChunksToKeep, Alignment, true); |