diff options
| author | Dan Engelbrecht <[email protected]> | 2022-03-23 22:11:11 +0100 |
|---|---|---|
| committer | Dan Engelbrecht <[email protected]> | 2022-03-31 11:29:27 +0200 |
| commit | 33a0466535c870aa816a608b108f1f8713778367 (patch) | |
| tree | fe222ffd2bcd180e2f9305ad4a8473e9bd2e99ba /zenstore/compactcas.cpp | |
| parent | No neeed to bookkeep moved chunk hashes (diff) | |
| download | zen-33a0466535c870aa816a608b108f1f8713778367.tar.xz zen-33a0466535c870aa816a608b108f1f8713778367.zip | |
Use simpler data structures
Diffstat (limited to 'zenstore/compactcas.cpp')
| -rw-r--r-- | zenstore/compactcas.cpp | 495 |
1 files changed, 253 insertions, 242 deletions
diff --git a/zenstore/compactcas.cpp b/zenstore/compactcas.cpp index 95fa00a5e..fcb3efd5f 100644 --- a/zenstore/compactcas.cpp +++ b/zenstore/compactcas.cpp @@ -58,7 +58,7 @@ namespace { } std::vector<CasDiskIndexEntry> MakeCasDiskEntries(const std::unordered_map<IoHash, BlockStoreDiskLocation>& MovedChunks, - const std::unordered_set<IoHash, IoHash::Hasher>& DeletedChunks) + const std::vector<IoHash>& DeletedChunks) { std::vector<CasDiskIndexEntry> result; result.reserve(MovedChunks.size()); @@ -380,21 +380,17 @@ CasContainerStrategy::UpdateLocations(const std::span<CasDiskIndexEntry>& Entrie void CasContainerStrategy::CollectGarbage(GcContext& GcCtx) { - namespace fs = std::filesystem; - // It collects all the blocks that we want to delete chunks from. For each such - // block we keep a list of chunks to retain. - // - // It will first remove any chunks that are flushed from the m_LocationMap. + // block we keep a list of chunks to retain and a list of chunks to delete. // - // It then checks to see if we want to purge any chunks that are in the currently - // active block. If so, we break off the current block and start on a new block, - // otherwise we just let the active block be. + // If there is a block that we are currently writing to, that block is omitted + // from the garbage collection. // // Next it will iterate over all blocks that we want to remove chunks from. // If the block is empty after removal of chunks we mark the block as pending // delete - we want to delete it as soon as there are no IoBuffers using the // block file. + // Once complete we update the m_LocationMap by removing the chunks. // // If the block is non-empty we write out the chunks we want to keep to a new // block file (creating new block files as needed). @@ -402,13 +398,11 @@ CasContainerStrategy::CollectGarbage(GcContext& GcCtx) // We update the index as we complete each new block file. This makes it possible // to break the GC if we want to limit time for execution. // - // GC can fairly parallell to regular operation - it will block while figuring - // out which chunks to remove and what blocks to rewrite but the actual - // reading and writing of data to new block files does not block regular operation. + // GC can fairly parallell to regular operation - it will block while taking + // a snapshot of the current m_LocationMap state. // // While moving blocks it will do a blocking operation and update the m_LocationMap - // after each new block is written and it will also block when figuring out the - // path to the next new block. + // after each new block is written and figuring out the path to the next new block. ZEN_INFO("collecting garbage from '{}'", m_Config.RootDirectory / m_ContainerBaseName); Stopwatch TotalTimer; @@ -468,12 +462,10 @@ CasContainerStrategy::CollectGarbage(GcContext& GcCtx) TotalChunkCount = LocationMap.size(); - std::unordered_set<uint32_t> BlocksToReWrite; - std::unordered_map<uint32_t, size_t> BlockIndexToChunkMapIndex; - std::vector<std::unordered_set<IoHash, IoHash::Hasher>> KeepChunks; - std::vector<std::unordered_set<IoHash, IoHash::Hasher>> DeleteChunks; + std::unordered_map<uint32_t, size_t> BlockIndexToChunkMapIndex; + std::vector<std::vector<IoHash> > KeepChunks; + std::vector<std::vector<IoHash> > DeleteChunks; - BlocksToReWrite.reserve(BlockCount); BlockIndexToChunkMapIndex.reserve(BlockCount); KeepChunks.reserve(BlockCount); DeleteChunks.reserve(BlockCount); @@ -510,18 +502,31 @@ CasContainerStrategy::CollectGarbage(GcContext& GcCtx) if (Keep) { auto& ChunkMap = KeepChunks[ChunkMapIndex]; - ChunkMap.insert(ChunkHash); + ChunkMap.push_back(ChunkHash); NewTotalSize += KeyIt->second.GetSize(); } else { auto& ChunkMap = DeleteChunks[ChunkMapIndex]; - ChunkMap.insert(ChunkHash); + ChunkMap.push_back(ChunkHash); DeleteCount++; - BlocksToReWrite.insert(BlockIndex); } }); + std::unordered_set<uint32_t> BlocksToReWrite; + BlocksToReWrite.reserve(BlockIndexToChunkMapIndex.size()); + for (const auto& Entry : BlockIndexToChunkMapIndex) + { + uint32_t BlockIndex = Entry.first; + size_t ChunkMapIndex = Entry.second; + const auto& ChunkMap = DeleteChunks[ChunkMapIndex]; + if (ChunkMap.empty()) + { + continue; + } + BlocksToReWrite.insert(BlockIndex); + } + const bool PerformDelete = GcCtx.IsDeletionMode() && GcCtx.CollectSmallObjects(); if (!PerformDelete) { @@ -1317,40 +1322,43 @@ TEST_CASE("compactcas.compact.totalsize") std::random_device rd; std::mt19937 g(rd()); - ScopedTemporaryDirectory TempDir; - - CasStoreConfiguration CasConfig; - CasConfig.RootDirectory = TempDir.Path(); +// for (uint32_t i = 0; i < 100; ++i) + { + ScopedTemporaryDirectory TempDir; - CreateDirectories(CasConfig.RootDirectory); + CasStoreConfiguration CasConfig; + CasConfig.RootDirectory = TempDir.Path(); - const uint64_t kChunkSize = 1024; - const int32_t kChunkCount = 16; + CreateDirectories(CasConfig.RootDirectory); - { - CasGc Gc; - CasContainerStrategy Cas(CasConfig, Gc); - Cas.Initialize("test", 65536, 16, true); + const uint64_t kChunkSize = 1024; + const int32_t kChunkCount = 16; - for (int32_t Idx = 0; Idx < kChunkCount; ++Idx) { - IoBuffer Chunk = CreateChunk(kChunkSize); - const IoHash Hash = HashBuffer(Chunk); - auto InsertResult = Cas.InsertChunk(Chunk, Hash); - ZEN_ASSERT(InsertResult.New); - } + CasGc Gc; + CasContainerStrategy Cas(CasConfig, Gc); + Cas.Initialize("test", 65536, 16, true); - const uint64_t TotalSize = Cas.StorageSize().DiskSize; - CHECK_EQ(kChunkSize * kChunkCount, TotalSize); - } + for (int32_t Idx = 0; Idx < kChunkCount; ++Idx) + { + IoBuffer Chunk = CreateChunk(kChunkSize); + const IoHash Hash = HashBuffer(Chunk); + auto InsertResult = Cas.InsertChunk(Chunk, Hash); + ZEN_ASSERT(InsertResult.New); + } - { - CasGc Gc; - CasContainerStrategy Cas(CasConfig, Gc); - Cas.Initialize("test", 65536, 16, false); + const uint64_t TotalSize = Cas.StorageSize().DiskSize; + CHECK_EQ(kChunkSize * kChunkCount, TotalSize); + } - const uint64_t TotalSize = Cas.StorageSize().DiskSize; - CHECK_EQ(kChunkSize * kChunkCount, TotalSize); + { + CasGc Gc; + CasContainerStrategy Cas(CasConfig, Gc); + Cas.Initialize("test", 65536, 16, false); + + const uint64_t TotalSize = Cas.StorageSize().DiskSize; + CHECK_EQ(kChunkSize * kChunkCount, TotalSize); + } } } @@ -1417,110 +1425,81 @@ TEST_CASE("compactcas.gc.removefile") TEST_CASE("compactcas.gc.compact") { - ScopedTemporaryDirectory TempDir; - - CasStoreConfiguration CasConfig; - CasConfig.RootDirectory = TempDir.Path(); - CreateDirectories(CasConfig.RootDirectory); - - CasGc Gc; - CasContainerStrategy Cas(CasConfig, Gc); - Cas.Initialize("cb", 2048, 1 << 4, true); - - uint64_t ChunkSizes[9] = {128, 541, 1023, 781, 218, 37, 4, 997, 5}; - std::vector<IoBuffer> Chunks; - Chunks.reserve(9); - for (uint64_t Size : ChunkSizes) +// for (uint32_t i = 0; i < 100; ++i) { - Chunks.push_back(CreateChunk(Size)); - } + ScopedTemporaryDirectory TempDir; - std::vector<IoHash> ChunkHashes; - ChunkHashes.reserve(9); - for (const IoBuffer& Chunk : Chunks) - { - ChunkHashes.push_back(IoHash::HashBuffer(Chunk.Data(), Chunk.Size())); - } + CasStoreConfiguration CasConfig; + CasConfig.RootDirectory = TempDir.Path(); + CreateDirectories(CasConfig.RootDirectory); - CHECK(Cas.InsertChunk(Chunks[0], ChunkHashes[0]).New); - CHECK(Cas.InsertChunk(Chunks[1], ChunkHashes[1]).New); - CHECK(Cas.InsertChunk(Chunks[2], ChunkHashes[2]).New); - CHECK(Cas.InsertChunk(Chunks[3], ChunkHashes[3]).New); - CHECK(Cas.InsertChunk(Chunks[4], ChunkHashes[4]).New); - CHECK(Cas.InsertChunk(Chunks[5], ChunkHashes[5]).New); - CHECK(Cas.InsertChunk(Chunks[6], ChunkHashes[6]).New); - CHECK(Cas.InsertChunk(Chunks[7], ChunkHashes[7]).New); - CHECK(Cas.InsertChunk(Chunks[8], ChunkHashes[8]).New); - - CHECK(Cas.HaveChunk(ChunkHashes[0])); - CHECK(Cas.HaveChunk(ChunkHashes[1])); - CHECK(Cas.HaveChunk(ChunkHashes[2])); - CHECK(Cas.HaveChunk(ChunkHashes[3])); - CHECK(Cas.HaveChunk(ChunkHashes[4])); - CHECK(Cas.HaveChunk(ChunkHashes[5])); - CHECK(Cas.HaveChunk(ChunkHashes[6])); - CHECK(Cas.HaveChunk(ChunkHashes[7])); - CHECK(Cas.HaveChunk(ChunkHashes[8])); - - uint64_t InitialSize = Cas.StorageSize().DiskSize; - - // Keep first and last - { - GcContext GcCtx; - GcCtx.CollectSmallObjects(true); + CasGc Gc; + CasContainerStrategy Cas(CasConfig, Gc); + Cas.Initialize("cb", 2048, 1 << 4, true); - std::vector<IoHash> KeepChunks; - KeepChunks.push_back(ChunkHashes[0]); - KeepChunks.push_back(ChunkHashes[8]); - GcCtx.ContributeCas(KeepChunks); + uint64_t ChunkSizes[9] = {128, 541, 1023, 781, 218, 37, 4, 997, 5}; + std::vector<IoBuffer> Chunks; + Chunks.reserve(9); + for (uint64_t Size : ChunkSizes) + { + Chunks.push_back(CreateChunk(Size)); + } - Cas.Flush(); - Cas.CollectGarbage(GcCtx); + std::vector<IoHash> ChunkHashes; + ChunkHashes.reserve(9); + for (const IoBuffer& Chunk : Chunks) + { + ChunkHashes.push_back(IoHash::HashBuffer(Chunk.Data(), Chunk.Size())); + } + + CHECK(Cas.InsertChunk(Chunks[0], ChunkHashes[0]).New); + CHECK(Cas.InsertChunk(Chunks[1], ChunkHashes[1]).New); + CHECK(Cas.InsertChunk(Chunks[2], ChunkHashes[2]).New); + CHECK(Cas.InsertChunk(Chunks[3], ChunkHashes[3]).New); + CHECK(Cas.InsertChunk(Chunks[4], ChunkHashes[4]).New); + CHECK(Cas.InsertChunk(Chunks[5], ChunkHashes[5]).New); + CHECK(Cas.InsertChunk(Chunks[6], ChunkHashes[6]).New); + CHECK(Cas.InsertChunk(Chunks[7], ChunkHashes[7]).New); + CHECK(Cas.InsertChunk(Chunks[8], ChunkHashes[8]).New); CHECK(Cas.HaveChunk(ChunkHashes[0])); - CHECK(!Cas.HaveChunk(ChunkHashes[1])); - CHECK(!Cas.HaveChunk(ChunkHashes[2])); - CHECK(!Cas.HaveChunk(ChunkHashes[3])); - CHECK(!Cas.HaveChunk(ChunkHashes[4])); - CHECK(!Cas.HaveChunk(ChunkHashes[5])); - CHECK(!Cas.HaveChunk(ChunkHashes[6])); - CHECK(!Cas.HaveChunk(ChunkHashes[7])); + CHECK(Cas.HaveChunk(ChunkHashes[1])); + CHECK(Cas.HaveChunk(ChunkHashes[2])); + CHECK(Cas.HaveChunk(ChunkHashes[3])); + CHECK(Cas.HaveChunk(ChunkHashes[4])); + CHECK(Cas.HaveChunk(ChunkHashes[5])); + CHECK(Cas.HaveChunk(ChunkHashes[6])); + CHECK(Cas.HaveChunk(ChunkHashes[7])); CHECK(Cas.HaveChunk(ChunkHashes[8])); - CHECK(ChunkHashes[0] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[0]))); - CHECK(ChunkHashes[8] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[8]))); - } + uint64_t InitialSize = Cas.StorageSize().DiskSize; - Cas.InsertChunk(Chunks[1], ChunkHashes[1]); - Cas.InsertChunk(Chunks[2], ChunkHashes[2]); - Cas.InsertChunk(Chunks[3], ChunkHashes[3]); - Cas.InsertChunk(Chunks[4], ChunkHashes[4]); - Cas.InsertChunk(Chunks[5], ChunkHashes[5]); - Cas.InsertChunk(Chunks[6], ChunkHashes[6]); - Cas.InsertChunk(Chunks[7], ChunkHashes[7]); + // Keep first and last + { + GcContext GcCtx; + GcCtx.CollectSmallObjects(true); - // Keep last - { - GcContext GcCtx; - GcCtx.CollectSmallObjects(true); - std::vector<IoHash> KeepChunks; - KeepChunks.push_back(ChunkHashes[8]); - GcCtx.ContributeCas(KeepChunks); + std::vector<IoHash> KeepChunks; + KeepChunks.push_back(ChunkHashes[0]); + KeepChunks.push_back(ChunkHashes[8]); + GcCtx.ContributeCas(KeepChunks); - Cas.Flush(); - Cas.CollectGarbage(GcCtx); - - CHECK(!Cas.HaveChunk(ChunkHashes[0])); - CHECK(!Cas.HaveChunk(ChunkHashes[1])); - CHECK(!Cas.HaveChunk(ChunkHashes[2])); - CHECK(!Cas.HaveChunk(ChunkHashes[3])); - CHECK(!Cas.HaveChunk(ChunkHashes[4])); - CHECK(!Cas.HaveChunk(ChunkHashes[5])); - CHECK(!Cas.HaveChunk(ChunkHashes[6])); - CHECK(!Cas.HaveChunk(ChunkHashes[7])); - CHECK(Cas.HaveChunk(ChunkHashes[8])); + Cas.Flush(); + Cas.CollectGarbage(GcCtx); - CHECK(ChunkHashes[8] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[8]))); + CHECK(Cas.HaveChunk(ChunkHashes[0])); + CHECK(!Cas.HaveChunk(ChunkHashes[1])); + CHECK(!Cas.HaveChunk(ChunkHashes[2])); + CHECK(!Cas.HaveChunk(ChunkHashes[3])); + CHECK(!Cas.HaveChunk(ChunkHashes[4])); + CHECK(!Cas.HaveChunk(ChunkHashes[5])); + CHECK(!Cas.HaveChunk(ChunkHashes[6])); + CHECK(!Cas.HaveChunk(ChunkHashes[7])); + CHECK(Cas.HaveChunk(ChunkHashes[8])); + + CHECK(ChunkHashes[0] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[0]))); + CHECK(ChunkHashes[8] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[8]))); + } Cas.InsertChunk(Chunks[1], ChunkHashes[1]); Cas.InsertChunk(Chunks[2], ChunkHashes[2]); @@ -1529,128 +1508,160 @@ TEST_CASE("compactcas.gc.compact") Cas.InsertChunk(Chunks[5], ChunkHashes[5]); Cas.InsertChunk(Chunks[6], ChunkHashes[6]); Cas.InsertChunk(Chunks[7], ChunkHashes[7]); - } - // Keep mixed - { - GcContext GcCtx; - GcCtx.CollectSmallObjects(true); - std::vector<IoHash> KeepChunks; - KeepChunks.push_back(ChunkHashes[1]); - KeepChunks.push_back(ChunkHashes[4]); - KeepChunks.push_back(ChunkHashes[7]); - GcCtx.ContributeCas(KeepChunks); + // Keep last + { + GcContext GcCtx; + GcCtx.CollectSmallObjects(true); + std::vector<IoHash> KeepChunks; + KeepChunks.push_back(ChunkHashes[8]); + GcCtx.ContributeCas(KeepChunks); - Cas.Flush(); - Cas.CollectGarbage(GcCtx); + Cas.Flush(); + Cas.CollectGarbage(GcCtx); - CHECK(!Cas.HaveChunk(ChunkHashes[0])); - CHECK(Cas.HaveChunk(ChunkHashes[1])); - CHECK(!Cas.HaveChunk(ChunkHashes[2])); - CHECK(!Cas.HaveChunk(ChunkHashes[3])); - CHECK(Cas.HaveChunk(ChunkHashes[4])); - CHECK(!Cas.HaveChunk(ChunkHashes[5])); - CHECK(!Cas.HaveChunk(ChunkHashes[6])); - CHECK(Cas.HaveChunk(ChunkHashes[7])); - CHECK(!Cas.HaveChunk(ChunkHashes[8])); + CHECK(!Cas.HaveChunk(ChunkHashes[0])); + CHECK(!Cas.HaveChunk(ChunkHashes[1])); + CHECK(!Cas.HaveChunk(ChunkHashes[2])); + CHECK(!Cas.HaveChunk(ChunkHashes[3])); + CHECK(!Cas.HaveChunk(ChunkHashes[4])); + CHECK(!Cas.HaveChunk(ChunkHashes[5])); + CHECK(!Cas.HaveChunk(ChunkHashes[6])); + CHECK(!Cas.HaveChunk(ChunkHashes[7])); + CHECK(Cas.HaveChunk(ChunkHashes[8])); + + CHECK(ChunkHashes[8] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[8]))); + + Cas.InsertChunk(Chunks[1], ChunkHashes[1]); + Cas.InsertChunk(Chunks[2], ChunkHashes[2]); + Cas.InsertChunk(Chunks[3], ChunkHashes[3]); + Cas.InsertChunk(Chunks[4], ChunkHashes[4]); + Cas.InsertChunk(Chunks[5], ChunkHashes[5]); + Cas.InsertChunk(Chunks[6], ChunkHashes[6]); + Cas.InsertChunk(Chunks[7], ChunkHashes[7]); + } - CHECK(ChunkHashes[1] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[1]))); - CHECK(ChunkHashes[4] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[4]))); - CHECK(ChunkHashes[7] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[7]))); + // Keep mixed + { + GcContext GcCtx; + GcCtx.CollectSmallObjects(true); + std::vector<IoHash> KeepChunks; + KeepChunks.push_back(ChunkHashes[1]); + KeepChunks.push_back(ChunkHashes[4]); + KeepChunks.push_back(ChunkHashes[7]); + GcCtx.ContributeCas(KeepChunks); - Cas.InsertChunk(Chunks[0], ChunkHashes[0]); - Cas.InsertChunk(Chunks[2], ChunkHashes[2]); - Cas.InsertChunk(Chunks[3], ChunkHashes[3]); - Cas.InsertChunk(Chunks[5], ChunkHashes[5]); - Cas.InsertChunk(Chunks[6], ChunkHashes[6]); - Cas.InsertChunk(Chunks[8], ChunkHashes[8]); - } + Cas.Flush(); + Cas.CollectGarbage(GcCtx); - // Keep multiple at end - { - GcContext GcCtx; - GcCtx.CollectSmallObjects(true); - std::vector<IoHash> KeepChunks; - KeepChunks.push_back(ChunkHashes[6]); - KeepChunks.push_back(ChunkHashes[7]); - KeepChunks.push_back(ChunkHashes[8]); - GcCtx.ContributeCas(KeepChunks); + CHECK(!Cas.HaveChunk(ChunkHashes[0])); + CHECK(Cas.HaveChunk(ChunkHashes[1])); + CHECK(!Cas.HaveChunk(ChunkHashes[2])); + CHECK(!Cas.HaveChunk(ChunkHashes[3])); + CHECK(Cas.HaveChunk(ChunkHashes[4])); + CHECK(!Cas.HaveChunk(ChunkHashes[5])); + CHECK(!Cas.HaveChunk(ChunkHashes[6])); + CHECK(Cas.HaveChunk(ChunkHashes[7])); + CHECK(!Cas.HaveChunk(ChunkHashes[8])); + + CHECK(ChunkHashes[1] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[1]))); + CHECK(ChunkHashes[4] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[4]))); + CHECK(ChunkHashes[7] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[7]))); + + Cas.InsertChunk(Chunks[0], ChunkHashes[0]); + Cas.InsertChunk(Chunks[2], ChunkHashes[2]); + Cas.InsertChunk(Chunks[3], ChunkHashes[3]); + Cas.InsertChunk(Chunks[5], ChunkHashes[5]); + Cas.InsertChunk(Chunks[6], ChunkHashes[6]); + Cas.InsertChunk(Chunks[8], ChunkHashes[8]); + } - Cas.Flush(); - Cas.CollectGarbage(GcCtx); - - CHECK(!Cas.HaveChunk(ChunkHashes[0])); - CHECK(!Cas.HaveChunk(ChunkHashes[1])); - CHECK(!Cas.HaveChunk(ChunkHashes[2])); - CHECK(!Cas.HaveChunk(ChunkHashes[3])); - CHECK(!Cas.HaveChunk(ChunkHashes[4])); - CHECK(!Cas.HaveChunk(ChunkHashes[5])); - CHECK(Cas.HaveChunk(ChunkHashes[6])); - CHECK(Cas.HaveChunk(ChunkHashes[7])); - CHECK(Cas.HaveChunk(ChunkHashes[8])); + // Keep multiple at end + { + GcContext GcCtx; + GcCtx.CollectSmallObjects(true); + std::vector<IoHash> KeepChunks; + KeepChunks.push_back(ChunkHashes[6]); + KeepChunks.push_back(ChunkHashes[7]); + KeepChunks.push_back(ChunkHashes[8]); + GcCtx.ContributeCas(KeepChunks); - CHECK(ChunkHashes[6] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[6]))); - CHECK(ChunkHashes[7] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[7]))); - CHECK(ChunkHashes[8] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[8]))); + Cas.Flush(); + Cas.CollectGarbage(GcCtx); - Cas.InsertChunk(Chunks[0], ChunkHashes[0]); - Cas.InsertChunk(Chunks[1], ChunkHashes[1]); - Cas.InsertChunk(Chunks[2], ChunkHashes[2]); - Cas.InsertChunk(Chunks[3], ChunkHashes[3]); - Cas.InsertChunk(Chunks[4], ChunkHashes[4]); - Cas.InsertChunk(Chunks[5], ChunkHashes[5]); - } + CHECK(!Cas.HaveChunk(ChunkHashes[0])); + CHECK(!Cas.HaveChunk(ChunkHashes[1])); + CHECK(!Cas.HaveChunk(ChunkHashes[2])); + CHECK(!Cas.HaveChunk(ChunkHashes[3])); + CHECK(!Cas.HaveChunk(ChunkHashes[4])); + CHECK(!Cas.HaveChunk(ChunkHashes[5])); + CHECK(Cas.HaveChunk(ChunkHashes[6])); + CHECK(Cas.HaveChunk(ChunkHashes[7])); + CHECK(Cas.HaveChunk(ChunkHashes[8])); + + CHECK(ChunkHashes[6] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[6]))); + CHECK(ChunkHashes[7] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[7]))); + CHECK(ChunkHashes[8] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[8]))); + + Cas.InsertChunk(Chunks[0], ChunkHashes[0]); + Cas.InsertChunk(Chunks[1], ChunkHashes[1]); + Cas.InsertChunk(Chunks[2], ChunkHashes[2]); + Cas.InsertChunk(Chunks[3], ChunkHashes[3]); + Cas.InsertChunk(Chunks[4], ChunkHashes[4]); + Cas.InsertChunk(Chunks[5], ChunkHashes[5]); + } - // Keep every other - { - GcContext GcCtx; - GcCtx.CollectSmallObjects(true); - std::vector<IoHash> KeepChunks; - KeepChunks.push_back(ChunkHashes[0]); - KeepChunks.push_back(ChunkHashes[2]); - KeepChunks.push_back(ChunkHashes[4]); - KeepChunks.push_back(ChunkHashes[6]); - KeepChunks.push_back(ChunkHashes[8]); - GcCtx.ContributeCas(KeepChunks); + // Keep every other + { + GcContext GcCtx; + GcCtx.CollectSmallObjects(true); + std::vector<IoHash> KeepChunks; + KeepChunks.push_back(ChunkHashes[0]); + KeepChunks.push_back(ChunkHashes[2]); + KeepChunks.push_back(ChunkHashes[4]); + KeepChunks.push_back(ChunkHashes[6]); + KeepChunks.push_back(ChunkHashes[8]); + GcCtx.ContributeCas(KeepChunks); - Cas.Flush(); - Cas.CollectGarbage(GcCtx); + Cas.Flush(); + Cas.CollectGarbage(GcCtx); - CHECK(Cas.HaveChunk(ChunkHashes[0])); - CHECK(!Cas.HaveChunk(ChunkHashes[1])); - CHECK(Cas.HaveChunk(ChunkHashes[2])); - CHECK(!Cas.HaveChunk(ChunkHashes[3])); - CHECK(Cas.HaveChunk(ChunkHashes[4])); - CHECK(!Cas.HaveChunk(ChunkHashes[5])); - CHECK(Cas.HaveChunk(ChunkHashes[6])); - CHECK(!Cas.HaveChunk(ChunkHashes[7])); - CHECK(Cas.HaveChunk(ChunkHashes[8])); + CHECK(Cas.HaveChunk(ChunkHashes[0])); + CHECK(!Cas.HaveChunk(ChunkHashes[1])); + CHECK(Cas.HaveChunk(ChunkHashes[2])); + CHECK(!Cas.HaveChunk(ChunkHashes[3])); + CHECK(Cas.HaveChunk(ChunkHashes[4])); + CHECK(!Cas.HaveChunk(ChunkHashes[5])); + CHECK(Cas.HaveChunk(ChunkHashes[6])); + CHECK(!Cas.HaveChunk(ChunkHashes[7])); + CHECK(Cas.HaveChunk(ChunkHashes[8])); + + CHECK(ChunkHashes[0] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[0]))); + CHECK(ChunkHashes[2] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[2]))); + CHECK(ChunkHashes[4] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[4]))); + CHECK(ChunkHashes[6] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[6]))); + CHECK(ChunkHashes[8] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[8]))); + + Cas.InsertChunk(Chunks[1], ChunkHashes[1]); + Cas.InsertChunk(Chunks[3], ChunkHashes[3]); + Cas.InsertChunk(Chunks[5], ChunkHashes[5]); + Cas.InsertChunk(Chunks[7], ChunkHashes[7]); + } + // Verify that we nicely appended blocks even after all GC operations CHECK(ChunkHashes[0] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[0]))); + CHECK(ChunkHashes[1] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[1]))); CHECK(ChunkHashes[2] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[2]))); + CHECK(ChunkHashes[3] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[3]))); CHECK(ChunkHashes[4] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[4]))); + CHECK(ChunkHashes[5] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[5]))); CHECK(ChunkHashes[6] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[6]))); + CHECK(ChunkHashes[7] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[7]))); CHECK(ChunkHashes[8] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[8]))); - Cas.InsertChunk(Chunks[1], ChunkHashes[1]); - Cas.InsertChunk(Chunks[3], ChunkHashes[3]); - Cas.InsertChunk(Chunks[5], ChunkHashes[5]); - Cas.InsertChunk(Chunks[7], ChunkHashes[7]); + uint64_t FinalSize = Cas.StorageSize().DiskSize; + CHECK(InitialSize == FinalSize); } - - // Verify that we nicely appended blocks even after all GC operations - CHECK(ChunkHashes[0] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[0]))); - CHECK(ChunkHashes[1] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[1]))); - CHECK(ChunkHashes[2] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[2]))); - CHECK(ChunkHashes[3] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[3]))); - CHECK(ChunkHashes[4] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[4]))); - CHECK(ChunkHashes[5] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[5]))); - CHECK(ChunkHashes[6] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[6]))); - CHECK(ChunkHashes[7] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[7]))); - CHECK(ChunkHashes[8] == IoHash::HashBuffer(Cas.FindChunk(ChunkHashes[8]))); - - uint64_t FinalSize = Cas.StorageSize().DiskSize; - CHECK(InitialSize == FinalSize); } TEST_CASE("compactcas.gc.deleteblockonopen") @@ -1881,7 +1892,7 @@ TEST_CASE("compactcas.legacyconversion") TEST_CASE("compactcas.threadedinsert") // * doctest::skip(true)) { - // for (uint32_t i = 0; i < 100; ++i) +// for (uint32_t i = 0; i < 100; ++i) { ScopedTemporaryDirectory TempDir; |