aboutsummaryrefslogtreecommitdiff
path: root/zenstore/compactcas.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2022-03-23 22:11:11 +0100
committerDan Engelbrecht <[email protected]>2022-03-31 11:29:27 +0200
commit33a0466535c870aa816a608b108f1f8713778367 (patch)
treefe222ffd2bcd180e2f9305ad4a8473e9bd2e99ba /zenstore/compactcas.cpp
parentNo neeed to bookkeep moved chunk hashes (diff)
downloadzen-33a0466535c870aa816a608b108f1f8713778367.tar.xz
zen-33a0466535c870aa816a608b108f1f8713778367.zip
Use simpler data structures
Diffstat (limited to 'zenstore/compactcas.cpp')
-rw-r--r--zenstore/compactcas.cpp495
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;