From 05178f7c18a48b21b9e260de282a86b91df26955 Mon Sep 17 00:00:00 2001 From: Dan Engelbrecht Date: Tue, 21 Nov 2023 15:06:25 +0100 Subject: compact separate for gc referencer (#533) - Refactor GCV2 so GcReferencer::RemoveExpiredData returns a store compactor, moving out the actual disk work from deleting items in the index. - Refactor GCV2 GcResult to reuse GcCompactStoreStats and GcStats - Make Compacting of stores non-parallell to not eat all the disk I/O when running GC --- src/zenserver/cache/structuredcachestore.cpp | 228 ++++++++++++++------------- 1 file changed, 118 insertions(+), 110 deletions(-) (limited to 'src/zenserver/cache/structuredcachestore.cpp') diff --git a/src/zenserver/cache/structuredcachestore.cpp b/src/zenserver/cache/structuredcachestore.cpp index cc6fefc76..25dfd103d 100644 --- a/src/zenserver/cache/structuredcachestore.cpp +++ b/src/zenserver/cache/structuredcachestore.cpp @@ -1957,14 +1957,14 @@ TEST_CASE("z$.newgc.basics") .CollectSmallObjects = false, .IsDeleteMode = false, .Verbose = true}); - CHECK_EQ(7u, Result.ReferencerStat.Count); - CHECK_EQ(0u, Result.ReferencerStat.Expired); - CHECK_EQ(0u, Result.ReferencerStat.Deleted); - CHECK_EQ(5u, Result.ReferenceStoreStat.Count); - CHECK_EQ(0u, Result.ReferenceStoreStat.Pruned); - CHECK_EQ(0u, Result.ReferenceStoreStat.Compacted); - CHECK_EQ(0u, Result.RemovedDisk); - CHECK_EQ(0u, Result.RemovedMemory); + CHECK_EQ(7u, Result.ReferencerStatSum.RemoveExpiredDataStats.CheckedCount); + CHECK_EQ(0u, Result.ReferencerStatSum.RemoveExpiredDataStats.FoundCount); + CHECK_EQ(0u, Result.ReferencerStatSum.RemoveExpiredDataStats.DeletedCount); + CHECK_EQ(5u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.CheckedCount); + CHECK_EQ(0u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.FoundCount); + CHECK_EQ(0u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.DeletedCount); + CHECK_EQ(0u, Result.CompactStoresStatSum.RemovedDisk); + CHECK_EQ(0u, Result.ReferencerStatSum.RemoveExpiredDataStats.FreedMemory); CHECK(ValidateCacheEntry(Zcs, CidStore, TearDrinkerBucket, CacheRecords[0], true, true)); CHECK(ValidateCacheEntry(Zcs, CidStore, TearDrinkerBucket, CacheRecords[1], true, true)); @@ -1991,14 +1991,14 @@ TEST_CASE("z$.newgc.basics") .CollectSmallObjects = false, .IsDeleteMode = false, .Verbose = true}); - CHECK_EQ(7u, Result.ReferencerStat.Count); - CHECK_EQ(1u, Result.ReferencerStat.Expired); - CHECK_EQ(0u, Result.ReferencerStat.Deleted); - CHECK_EQ(5u, Result.ReferenceStoreStat.Count); - CHECK_EQ(0u, Result.ReferenceStoreStat.Pruned); - CHECK_EQ(0u, Result.ReferenceStoreStat.Compacted); - CHECK_EQ(0u, Result.RemovedDisk); - CHECK_EQ(0u, Result.RemovedMemory); + CHECK_EQ(7u, Result.ReferencerStatSum.RemoveExpiredDataStats.CheckedCount); + CHECK_EQ(1u, Result.ReferencerStatSum.RemoveExpiredDataStats.FoundCount); + CHECK_EQ(0u, Result.ReferencerStatSum.RemoveExpiredDataStats.DeletedCount); + CHECK_EQ(5u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.CheckedCount); + CHECK_EQ(0u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.FoundCount); + CHECK_EQ(0u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.DeletedCount); + CHECK_EQ(0u, Result.CompactStoresStatSum.RemovedDisk); + CHECK_EQ(0u, Result.ReferencerStatSum.RemoveExpiredDataStats.FreedMemory); CHECK(ValidateCacheEntry(Zcs, CidStore, TearDrinkerBucket, CacheRecords[0], true, true)); CHECK(ValidateCacheEntry(Zcs, CidStore, TearDrinkerBucket, CacheRecords[1], true, true)); @@ -2025,14 +2025,14 @@ TEST_CASE("z$.newgc.basics") .CollectSmallObjects = true, .IsDeleteMode = false, .Verbose = true}); - CHECK_EQ(7u, Result.ReferencerStat.Count); - CHECK_EQ(7u, Result.ReferencerStat.Expired); - CHECK_EQ(0u, Result.ReferencerStat.Deleted); - CHECK_EQ(5u, Result.ReferenceStoreStat.Count); - CHECK_EQ(0u, Result.ReferenceStoreStat.Pruned); - CHECK_EQ(0u, Result.ReferenceStoreStat.Compacted); - CHECK_EQ(0u, Result.RemovedDisk); - CHECK_EQ(0u, Result.RemovedMemory); + CHECK_EQ(7u, Result.ReferencerStatSum.RemoveExpiredDataStats.CheckedCount); + CHECK_EQ(7u, Result.ReferencerStatSum.RemoveExpiredDataStats.FoundCount); + CHECK_EQ(0u, Result.ReferencerStatSum.RemoveExpiredDataStats.DeletedCount); + CHECK_EQ(5u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.CheckedCount); + CHECK_EQ(0u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.FoundCount); + CHECK_EQ(0u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.DeletedCount); + CHECK_EQ(0u, Result.CompactStoresStatSum.RemovedDisk); + CHECK_EQ(0u, Result.ReferencerStatSum.RemoveExpiredDataStats.FreedMemory); CHECK(ValidateCacheEntry(Zcs, CidStore, TearDrinkerBucket, CacheRecords[0], true, true)); CHECK(ValidateCacheEntry(Zcs, CidStore, TearDrinkerBucket, CacheRecords[1], true, true)); @@ -2060,14 +2060,14 @@ TEST_CASE("z$.newgc.basics") .IsDeleteMode = true, .SkipCidDelete = true, .Verbose = true}); - CHECK_EQ(7u, Result.ReferencerStat.Count); - CHECK_EQ(1u, Result.ReferencerStat.Expired); - CHECK_EQ(1u, Result.ReferencerStat.Deleted); - CHECK_EQ(0u, Result.ReferenceStoreStat.Count); - CHECK_EQ(0u, Result.ReferenceStoreStat.Pruned); - CHECK_EQ(0u, Result.ReferenceStoreStat.Compacted); - CHECK_EQ(CacheEntries[UnstructuredCacheValues[2]].Data.GetSize(), Result.RemovedDisk); - CHECK_EQ(0u, Result.RemovedMemory); + CHECK_EQ(7u, Result.ReferencerStatSum.RemoveExpiredDataStats.CheckedCount); + CHECK_EQ(1u, Result.ReferencerStatSum.RemoveExpiredDataStats.FoundCount); + CHECK_EQ(1u, Result.ReferencerStatSum.RemoveExpiredDataStats.DeletedCount); + CHECK_EQ(0u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.CheckedCount); + CHECK_EQ(0u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.FoundCount); + CHECK_EQ(0u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.DeletedCount); + CHECK_EQ(CacheEntries[UnstructuredCacheValues[2]].Data.GetSize(), Result.CompactStoresStatSum.RemovedDisk); + CHECK_EQ(0u, Result.ReferencerStatSum.RemoveExpiredDataStats.FreedMemory); CHECK(ValidateCacheEntry(Zcs, CidStore, TearDrinkerBucket, CacheRecords[0], true, true)); CHECK(ValidateCacheEntry(Zcs, CidStore, TearDrinkerBucket, CacheRecords[1], true, true)); @@ -2095,14 +2095,14 @@ TEST_CASE("z$.newgc.basics") .IsDeleteMode = true, .SkipCidDelete = true, .Verbose = true}); - CHECK_EQ(7u, Result.ReferencerStat.Count); - CHECK_EQ(7u, Result.ReferencerStat.Expired); - CHECK_EQ(7u, Result.ReferencerStat.Deleted); - CHECK_EQ(0u, Result.ReferenceStoreStat.Count); - CHECK_EQ(0u, Result.ReferenceStoreStat.Pruned); - CHECK_EQ(0u, Result.ReferenceStoreStat.Compacted); - CHECK_GE(Result.RemovedDisk, 0); - CHECK_EQ(0u, Result.RemovedMemory); + CHECK_EQ(7u, Result.ReferencerStatSum.RemoveExpiredDataStats.CheckedCount); + CHECK_EQ(7u, Result.ReferencerStatSum.RemoveExpiredDataStats.FoundCount); + CHECK_EQ(7u, Result.ReferencerStatSum.RemoveExpiredDataStats.DeletedCount); + CHECK_EQ(0u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.CheckedCount); + CHECK_EQ(0u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.FoundCount); + CHECK_EQ(0u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.DeletedCount); + CHECK_GE(Result.CompactStoresStatSum.RemovedDisk, 0); + CHECK_EQ(0u, Result.ReferencerStatSum.RemoveExpiredDataStats.FreedMemory); CHECK(ValidateCacheEntry(Zcs, CidStore, TearDrinkerBucket, CacheRecords[0], false, true)); CHECK(ValidateCacheEntry(Zcs, CidStore, TearDrinkerBucket, CacheRecords[1], false, true)); @@ -2130,17 +2130,20 @@ TEST_CASE("z$.newgc.basics") .IsDeleteMode = true, .SkipCidDelete = false, .Verbose = true}); - CHECK_EQ(7u, Result.ReferencerStat.Count); - CHECK_EQ(1u, Result.ReferencerStat.Expired); // Only one cache value is pruned/deleted as that is the only large item in the cache - // (all other large items as in cas) - CHECK_EQ(1u, Result.ReferencerStat.Deleted); - CHECK_EQ(5u, Result.ReferenceStoreStat.Count); + CHECK_EQ(7u, Result.ReferencerStatSum.RemoveExpiredDataStats.CheckedCount); + CHECK_EQ(1u, + Result.ReferencerStatSum.RemoveExpiredDataStats.FoundCount); // Only one cache value is pruned/deleted as that is the only + // large item in the cache (all other large items as in cas) + CHECK_EQ(1u, Result.ReferencerStatSum.RemoveExpiredDataStats.DeletedCount); + CHECK_EQ(5u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.CheckedCount); CHECK_EQ(0u, - Result.ReferenceStoreStat - .Pruned); // We won't remove any references since all referencers are small which retains all references - CHECK_EQ(0u, Result.ReferenceStoreStat.Compacted); - CHECK_EQ(CacheEntries[UnstructuredCacheValues[2]].Data.GetSize(), Result.RemovedDisk); - CHECK_EQ(0u, Result.RemovedMemory); + Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats + .FoundCount); // We won't remove any references since all referencers are small which retains all references + CHECK_EQ(0u, + Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats + .DeletedCount); // We won't remove any references since all referencers are small which retains all references + CHECK_EQ(CacheEntries[UnstructuredCacheValues[2]].Data.GetSize(), Result.CompactStoresStatSum.RemovedDisk); + CHECK_EQ(0u, Result.ReferencerStatSum.RemoveExpiredDataStats.FreedMemory); CHECK(ValidateCacheEntry(Zcs, CidStore, TearDrinkerBucket, CacheRecords[0], true, true)); CHECK(ValidateCacheEntry(Zcs, CidStore, TearDrinkerBucket, CacheRecords[1], true, true)); @@ -2168,14 +2171,14 @@ TEST_CASE("z$.newgc.basics") .IsDeleteMode = true, .SkipCidDelete = false, .Verbose = true}); - CHECK_EQ(7u, Result.ReferencerStat.Count); - CHECK_EQ(7u, Result.ReferencerStat.Expired); - CHECK_EQ(7u, Result.ReferencerStat.Deleted); - CHECK_EQ(5u, Result.ReferenceStoreStat.Count); - CHECK_EQ(5u, Result.ReferenceStoreStat.Pruned); - CHECK_EQ(5u, Result.ReferenceStoreStat.Compacted); - CHECK_GT(Result.RemovedDisk, 0); - CHECK_EQ(0u, Result.RemovedMemory); + CHECK_EQ(7u, Result.ReferencerStatSum.RemoveExpiredDataStats.CheckedCount); + CHECK_EQ(7u, Result.ReferencerStatSum.RemoveExpiredDataStats.FoundCount); + CHECK_EQ(7u, Result.ReferencerStatSum.RemoveExpiredDataStats.DeletedCount); + CHECK_EQ(5u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.CheckedCount); + CHECK_EQ(5u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.FoundCount); + CHECK_EQ(5u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.DeletedCount); + CHECK_GT(Result.CompactStoresStatSum.RemovedDisk, 0); + CHECK_EQ(0u, Result.ReferencerStatSum.RemoveExpiredDataStats.FreedMemory); CHECK(ValidateCacheEntry(Zcs, CidStore, TearDrinkerBucket, CacheRecords[0], false, false)); CHECK(ValidateCacheEntry(Zcs, CidStore, TearDrinkerBucket, CacheRecords[1], false, false)); @@ -2200,20 +2203,22 @@ TEST_CASE("z$.newgc.basics") Zcs.SetAccessTime(TearDrinkerBucket, CacheRecords[0], GcClock::Now() + std::chrono::hours(2)); - GcResult Result = Gc.CollectGarbage(GcSettings{.CacheExpireTime = GcClock::Now() + std::chrono::hours(1), - .ProjectStoreExpireTime = GcClock::Now() + std::chrono::hours(1), - .CollectSmallObjects = true, - .IsDeleteMode = true, - .SkipCidDelete = true, - .Verbose = true}); - CHECK_EQ(7u, Result.ReferencerStat.Count); - CHECK_EQ(6u, Result.ReferencerStat.Expired); - CHECK_EQ(6u, Result.ReferencerStat.Deleted); - CHECK_EQ(0u, Result.ReferenceStoreStat.Count); - CHECK_EQ(0u, Result.ReferenceStoreStat.Pruned); - CHECK_EQ(0u, Result.ReferenceStoreStat.Compacted); - CHECK_GT(Result.RemovedDisk, 0); - CHECK_EQ(0u, Result.RemovedMemory); + GcResult Result = Gc.CollectGarbage(GcSettings{.CacheExpireTime = GcClock::Now() + std::chrono::hours(1), + .ProjectStoreExpireTime = GcClock::Now() + std::chrono::hours(1), + .CollectSmallObjects = true, + .IsDeleteMode = true, + .SkipCidDelete = true, + .Verbose = true, + .CompactBlockUsageThresholdPercent = 100}); + CHECK_EQ(7u, Result.ReferencerStatSum.RemoveExpiredDataStats.CheckedCount); + CHECK_EQ(6u, Result.ReferencerStatSum.RemoveExpiredDataStats.FoundCount); + CHECK_EQ(6u, Result.ReferencerStatSum.RemoveExpiredDataStats.DeletedCount); + CHECK_EQ(0u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.CheckedCount); + CHECK_EQ(0u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.FoundCount); + CHECK_EQ(0u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.DeletedCount); + uint64_t MinExpectedRemoveSize = CacheEntries[UnstructuredCacheValues[2]].Data.GetSize(); + CHECK_LT(MinExpectedRemoveSize, Result.CompactStoresStatSum.RemovedDisk); + CHECK_EQ(0u, Result.ReferencerStatSum.RemoveExpiredDataStats.FreedMemory); CHECK(ValidateCacheEntry(Zcs, CidStore, TearDrinkerBucket, CacheRecords[0], true, true)); CHECK(ValidateCacheEntry(Zcs, CidStore, TearDrinkerBucket, CacheRecords[1], false, true)); @@ -2245,14 +2250,14 @@ TEST_CASE("z$.newgc.basics") .IsDeleteMode = true, .SkipCidDelete = false, .Verbose = true}); - CHECK_EQ(7u, Result.ReferencerStat.Count); - CHECK_EQ(5u, Result.ReferencerStat.Expired); - CHECK_EQ(5u, Result.ReferencerStat.Deleted); - CHECK_EQ(5u, Result.ReferenceStoreStat.Count); - CHECK_EQ(0u, Result.ReferenceStoreStat.Pruned); - CHECK_EQ(0u, Result.ReferenceStoreStat.Compacted); - CHECK_GT(Result.RemovedDisk, 0); - CHECK_EQ(0u, Result.RemovedMemory); + CHECK_EQ(7u, Result.ReferencerStatSum.RemoveExpiredDataStats.CheckedCount); + CHECK_EQ(5u, Result.ReferencerStatSum.RemoveExpiredDataStats.FoundCount); + CHECK_EQ(5u, Result.ReferencerStatSum.RemoveExpiredDataStats.DeletedCount); + CHECK_EQ(5u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.CheckedCount); + CHECK_EQ(0u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.FoundCount); + CHECK_EQ(0u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.DeletedCount); + CHECK_GT(Result.CompactStoresStatSum.RemovedDisk, 0); + CHECK_EQ(0u, Result.ReferencerStatSum.RemoveExpiredDataStats.FreedMemory); CHECK(ValidateCacheEntry(Zcs, CidStore, TearDrinkerBucket, CacheRecords[0], true, true)); CHECK(ValidateCacheEntry(Zcs, CidStore, TearDrinkerBucket, CacheRecords[1], true, true)); @@ -2285,14 +2290,14 @@ TEST_CASE("z$.newgc.basics") .IsDeleteMode = true, .SkipCidDelete = false, .Verbose = true}); - CHECK_EQ(7u, Result.ReferencerStat.Count); - CHECK_EQ(4u, Result.ReferencerStat.Expired); - CHECK_EQ(4u, Result.ReferencerStat.Deleted); - CHECK_EQ(5u, Result.ReferenceStoreStat.Count); - CHECK_EQ(5u, Result.ReferenceStoreStat.Pruned); - CHECK_EQ(5u, Result.ReferenceStoreStat.Compacted); - CHECK_GT(Result.RemovedDisk, 0); - CHECK_EQ(0u, Result.RemovedMemory); + CHECK_EQ(7u, Result.ReferencerStatSum.RemoveExpiredDataStats.CheckedCount); + CHECK_EQ(4u, Result.ReferencerStatSum.RemoveExpiredDataStats.FoundCount); + CHECK_EQ(4u, Result.ReferencerStatSum.RemoveExpiredDataStats.DeletedCount); + CHECK_EQ(5u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.CheckedCount); + CHECK_EQ(5u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.FoundCount); + CHECK_EQ(5u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.DeletedCount); + CHECK_GT(Result.CompactStoresStatSum.RemovedDisk, 0); + CHECK_EQ(0u, Result.ReferencerStatSum.RemoveExpiredDataStats.FreedMemory); CHECK(ValidateCacheEntry(Zcs, CidStore, TearDrinkerBucket, CacheRecords[0], false, false)); CHECK(ValidateCacheEntry(Zcs, CidStore, TearDrinkerBucket, CacheRecords[1], false, false)); @@ -2329,22 +2334,23 @@ TEST_CASE("z$.newgc.basics") Zcs.SetAccessTime(TearDrinkerBucket, UnstructuredCacheValues[2], GcClock::Now() + std::chrono::hours(2)); Zcs.SetAccessTime(TearDrinkerBucket, UnstructuredCacheValues[3], GcClock::Now() + std::chrono::hours(2)); - GcResult Result = Gc.CollectGarbage(GcSettings{.CacheExpireTime = GcClock::Now() + std::chrono::hours(1), - .ProjectStoreExpireTime = GcClock::Now() + std::chrono::hours(1), - .CollectSmallObjects = true, - .IsDeleteMode = true, - .SkipCidDelete = true, - .Verbose = true}); - CHECK_EQ(7u, Result.ReferencerStat.Count); - CHECK_EQ(4u, Result.ReferencerStat.Expired); - CHECK_EQ(4u, Result.ReferencerStat.Deleted); - CHECK_EQ(0u, Result.ReferenceStoreStat.Count); - CHECK_EQ(0u, Result.ReferenceStoreStat.Pruned); - CHECK_EQ(0u, Result.ReferenceStoreStat.Compacted); - CHECK_GT(Result.RemovedDisk, 0); + GcResult Result = Gc.CollectGarbage(GcSettings{.CacheExpireTime = GcClock::Now() + std::chrono::hours(1), + .ProjectStoreExpireTime = GcClock::Now() + std::chrono::hours(1), + .CollectSmallObjects = true, + .IsDeleteMode = true, + .SkipCidDelete = true, + .Verbose = true, + .CompactBlockUsageThresholdPercent = 100}); + CHECK_EQ(7u, Result.ReferencerStatSum.RemoveExpiredDataStats.CheckedCount); + CHECK_EQ(4u, Result.ReferencerStatSum.RemoveExpiredDataStats.FoundCount); + CHECK_EQ(4u, Result.ReferencerStatSum.RemoveExpiredDataStats.DeletedCount); + CHECK_EQ(0u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.CheckedCount); + CHECK_EQ(0u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.FoundCount); + CHECK_EQ(0u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.DeletedCount); + CHECK_GT(Result.CompactStoresStatSum.RemovedDisk, 0); uint64_t MemoryClean = CacheEntries[CacheRecords[0]].Data.GetSize() + CacheEntries[CacheRecords[1]].Data.GetSize() + CacheEntries[CacheRecords[2]].Data.GetSize() + CacheEntries[UnstructuredCacheValues[0]].Data.GetSize(); - CHECK_EQ(MemoryClean, Result.RemovedMemory); + CHECK_EQ(MemoryClean, Result.ReferencerStatSum.RemoveExpiredDataStats.FreedMemory); CHECK(ValidateCacheEntry(Zcs, CidStore, TearDrinkerBucket, CacheRecords[0], false, true)); CHECK(ValidateCacheEntry(Zcs, CidStore, TearDrinkerBucket, CacheRecords[1], false, true)); @@ -2393,15 +2399,17 @@ TEST_CASE("z$.newgc.basics") .IsDeleteMode = true, .SkipCidDelete = false, .Verbose = true}); - CHECK_EQ(8u, Result.ReferencerStat.Count); - CHECK_EQ(1u, Result.ReferencerStat.Expired); - CHECK_EQ(1u, Result.ReferencerStat.Deleted); - CHECK_EQ(9u, Result.ReferenceStoreStat.Count); - CHECK_EQ(4u, Result.ReferenceStoreStat.Pruned); - CHECK_EQ(4u, Result.ReferenceStoreStat.Compacted); - CHECK_EQ(Attachments[1].second.GetCompressed().GetSize() + Attachments[3].second.GetCompressed().GetSize(), Result.RemovedDisk); + // Write block can't be compacted so Compacted will be less than Deleted + CHECK_EQ(8u, Result.ReferencerStatSum.RemoveExpiredDataStats.CheckedCount); + CHECK_EQ(1u, Result.ReferencerStatSum.RemoveExpiredDataStats.FoundCount); + CHECK_EQ(1u, Result.ReferencerStatSum.RemoveExpiredDataStats.DeletedCount); + CHECK_EQ(9u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.CheckedCount); + CHECK_EQ(4u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.FoundCount); + CHECK_EQ(4u, Result.ReferenceStoreStatSum.RemoveUnreferencedDataStats.DeletedCount); + CHECK_EQ(Attachments[1].second.GetCompressed().GetSize() + Attachments[3].second.GetCompressed().GetSize(), + Result.CompactStoresStatSum.RemovedDisk); uint64_t MemoryClean = CacheEntries[CacheRecord].Data.GetSize(); - CHECK_EQ(MemoryClean, Result.RemovedMemory); + CHECK_EQ(MemoryClean, Result.ReferencerStatSum.RemoveExpiredDataStats.FreedMemory); } } -- cgit v1.2.3 From 1bbdc86732464170c2e7c6145a5a19cdb48fe396 Mon Sep 17 00:00:00 2001 From: Dan Engelbrecht Date: Fri, 1 Dec 2023 04:48:58 -0500 Subject: add separate PreCache step for GcReferenceChecker (#578) - Improvement: GCv2: Use separate PreCache step to improve concurrency when checking references - Improvement: GCv2: Improved verbose logging - Improvement: GCv2: Sort chunks to read by block/offset when finding references - Improvement: GCv2: Exit as soon as no more unreferenced items are left --- src/zenserver/cache/structuredcachestore.cpp | 99 ++++++++++++++++++---------- 1 file changed, 66 insertions(+), 33 deletions(-) (limited to 'src/zenserver/cache/structuredcachestore.cpp') diff --git a/src/zenserver/cache/structuredcachestore.cpp b/src/zenserver/cache/structuredcachestore.cpp index 25dfd103d..9155e209c 100644 --- a/src/zenserver/cache/structuredcachestore.cpp +++ b/src/zenserver/cache/structuredcachestore.cpp @@ -816,16 +816,28 @@ namespace testutils { return {Key, Buffer}; } + struct FalseType + { + static const bool Enabled = false; + }; + struct TrueType + { + static const bool Enabled = true; + }; + } // namespace testutils -TEST_CASE("z$.store") +TEST_CASE_TEMPLATE("z$.store", ReferenceCaching, testutils::FalseType, testutils::TrueType) { ScopedTemporaryDirectory TempDir; GcManager Gc; auto JobQueue = MakeJobQueue(1, "testqueue"); - ZenCacheNamespace Zcs(Gc, *JobQueue, TempDir.Path() / "cache", {}); + ZenCacheNamespace Zcs(Gc, + *JobQueue, + TempDir.Path() / "cache", + {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = ReferenceCaching::Enabled}}}); const int kIterationCount = 100; @@ -859,7 +871,7 @@ TEST_CASE("z$.store") } } -TEST_CASE("z$.size") +TEST_CASE_TEMPLATE("z$.size", ReferenceCaching, testutils::FalseType, testutils::TrueType) { auto JobQueue = MakeJobQueue(1, "testqueue"); @@ -881,7 +893,10 @@ TEST_CASE("z$.size") { GcManager Gc; - ZenCacheNamespace Zcs(Gc, *JobQueue, TempDir.Path() / "cache", {}); + ZenCacheNamespace Zcs(Gc, + *JobQueue, + TempDir.Path() / "cache", + {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = ReferenceCaching::Enabled}}}); CbObject CacheValue = CreateCacheValue(Zcs.GetConfig().DiskLayerConfig.BucketConfig.MemCacheSizeThreshold - 256); @@ -915,7 +930,10 @@ TEST_CASE("z$.size") { GcManager Gc; - ZenCacheNamespace Zcs(Gc, *JobQueue, TempDir.Path() / "cache", {}); + ZenCacheNamespace Zcs(Gc, + *JobQueue, + TempDir.Path() / "cache", + {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = ReferenceCaching::Enabled}}}); const GcStorageSize SerializedSize = Zcs.StorageSize(); CHECK_EQ(SerializedSize.MemorySize, 0); @@ -939,7 +957,10 @@ TEST_CASE("z$.size") { GcManager Gc; - ZenCacheNamespace Zcs(Gc, *JobQueue, TempDir.Path() / "cache", {}); + ZenCacheNamespace Zcs(Gc, + *JobQueue, + TempDir.Path() / "cache", + {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = ReferenceCaching::Enabled}}}); CbObject CacheValue = CreateCacheValue(Zcs.GetConfig().DiskLayerConfig.BucketConfig.MemCacheSizeThreshold + 64); @@ -959,7 +980,10 @@ TEST_CASE("z$.size") { GcManager Gc; - ZenCacheNamespace Zcs(Gc, *JobQueue, TempDir.Path() / "cache", {}); + ZenCacheNamespace Zcs(Gc, + *JobQueue, + TempDir.Path() / "cache", + {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = ReferenceCaching::Enabled}}}); const GcStorageSize SerializedSize = Zcs.StorageSize(); CHECK_EQ(SerializedSize.MemorySize, 0); @@ -974,7 +998,7 @@ TEST_CASE("z$.size") } } -TEST_CASE("z$.gc") +TEST_CASE_TEMPLATE("z$.gc", ReferenceCaching, testutils::FalseType, testutils::TrueType) { using namespace testutils; @@ -1001,7 +1025,7 @@ TEST_CASE("z$.gc") ZenCacheNamespace Zcs(Gc, *JobQueue, TempDir.Path() / "cache", - {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = true}}}); + {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = ReferenceCaching::Enabled}}}); const auto Bucket = "teardrinker"sv; // Create a cache record @@ -1041,7 +1065,7 @@ TEST_CASE("z$.gc") ZenCacheNamespace Zcs(Gc, *JobQueue, TempDir.Path() / "cache", - {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = true}}}); + {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = ReferenceCaching::Enabled}}}); std::vector Keep; // Collect garbage with 1 hour max cache duration @@ -1065,7 +1089,7 @@ TEST_CASE("z$.gc") ZenCacheNamespace Zcs(Gc, *JobQueue, TempDir.Path() / "cache", - {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = true}}}); + {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = ReferenceCaching::Enabled}}}); const auto Bucket = "fortysixandtwo"sv; const GcClock::TimePoint CurrentTime = GcClock::Now(); @@ -1114,7 +1138,7 @@ TEST_CASE("z$.gc") ZenCacheNamespace Zcs(Gc, *JobQueue, TempDir.Path() / "cache", - {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = true}}}); + {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = ReferenceCaching::Enabled}}}); const auto Bucket = "rightintwo"sv; std::vector Keys{CreateKey(1), CreateKey(2), CreateKey(3)}; @@ -1162,13 +1186,13 @@ TEST_CASE("z$.gc") ZenCacheNamespace Zcs(Gc, *JobQueue, TempDir.Path() / "cache", - {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = true}}}); + {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = ReferenceCaching::Enabled}}}); CHECK_EQ(0, Zcs.StorageSize().DiskSize); } } } -TEST_CASE("z$.threadedinsert") // * doctest::skip(true)) +TEST_CASE_TEMPLATE("z$.threadedinsert", ReferenceCaching, testutils::FalseType, testutils::TrueType) // * doctest::skip(true)) { // for (uint32_t i = 0; i < 100; ++i) { @@ -1219,7 +1243,10 @@ TEST_CASE("z$.threadedinsert") // * doctest::skip(true)) WorkerThreadPool ThreadPool(4); GcManager Gc; auto JobQueue = MakeJobQueue(1, "testqueue"); - ZenCacheNamespace Zcs(Gc, *JobQueue, TempDir.Path(), {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = true}}}); + ZenCacheNamespace Zcs(Gc, + *JobQueue, + TempDir.Path(), + {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = ReferenceCaching::Enabled}}}); { std::atomic WorkCompleted = 0; @@ -1648,7 +1675,7 @@ TEST_CASE("z$.drop.namespace") } } -TEST_CASE("z$.blocked.disklayer.put") +TEST_CASE_TEMPLATE("z$.blocked.disklayer.put", ReferenceCaching, testutils::FalseType, testutils::TrueType) { ScopedTemporaryDirectory TempDir; @@ -1665,7 +1692,10 @@ TEST_CASE("z$.blocked.disklayer.put") GcManager Gc; auto JobQueue = MakeJobQueue(1, "testqueue"); - ZenCacheNamespace Zcs(Gc, *JobQueue, TempDir.Path() / "cache", {}); + ZenCacheNamespace Zcs(Gc, + *JobQueue, + TempDir.Path() / "cache", + {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = ReferenceCaching::Enabled}}}); CbObject CacheValue = CreateCacheValue(64 * 1024 + 64); @@ -1701,7 +1731,7 @@ TEST_CASE("z$.blocked.disklayer.put") CHECK(memcmp(NewView.GetData(), Buffer2.GetData(), NewView.GetSize()) == 0); } -TEST_CASE("z$.scrub") +TEST_CASE_TEMPLATE("z$.scrub", ReferenceCaching, testutils::FalseType, testutils::TrueType) { ScopedTemporaryDirectory TempDir; @@ -1760,7 +1790,10 @@ TEST_CASE("z$.scrub") GcManager Gc; CidStore CidStore(Gc); auto JobQueue = MakeJobQueue(1, "testqueue"); - ZenCacheNamespace Zcs(Gc, *JobQueue, TempDir.Path() / "cache", {}); + ZenCacheNamespace Zcs(Gc, + *JobQueue, + TempDir.Path() / "cache", + {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = ReferenceCaching::Enabled}}}); CidStoreConfiguration CidConfig = {.RootDirectory = TempDir.Path() / "cas", .TinyValueThreshold = 1024, .HugeValueThreshold = 4096}; CidStore.Initialize(CidConfig); @@ -1795,7 +1828,7 @@ TEST_CASE("z$.scrub") CHECK(ScrubCtx.BadCids().GetSize() == 0); } -TEST_CASE("z$.newgc.basics") +TEST_CASE_TEMPLATE("z$.newgc.basics", ReferenceCaching, testutils::FalseType, testutils::TrueType) { using namespace testutils; @@ -1915,7 +1948,7 @@ TEST_CASE("z$.newgc.basics") ZenCacheNamespace Zcs(Gc, *JobQueue, TempDir.Path() / "cache", - {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = true}}}); + {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = ReferenceCaching::Enabled}}}); // Create some basic data { @@ -1949,7 +1982,7 @@ TEST_CASE("z$.newgc.basics") ZenCacheNamespace Zcs(Gc, *JobQueue, TempDir.Path() / "cache", - {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = true}}}); + {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = ReferenceCaching::Enabled}}}); CHECK_EQ(7, Zcs.GetBucketInfo(TearDrinkerBucket).value().DiskLayerInfo.EntryCount); GcResult Result = Gc.CollectGarbage(GcSettings{.CacheExpireTime = GcClock::Now() - std::chrono::hours(1), @@ -1983,7 +2016,7 @@ TEST_CASE("z$.newgc.basics") ZenCacheNamespace Zcs(Gc, *JobQueue, TempDir.Path() / "cache", - {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = true}}}); + {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = ReferenceCaching::Enabled}}}); CHECK_EQ(7, Zcs.GetBucketInfo(TearDrinkerBucket).value().DiskLayerInfo.EntryCount); GcResult Result = Gc.CollectGarbage(GcSettings{.CacheExpireTime = GcClock::Now() + std::chrono::hours(1), @@ -2017,7 +2050,7 @@ TEST_CASE("z$.newgc.basics") ZenCacheNamespace Zcs(Gc, *JobQueue, TempDir.Path() / "cache", - {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = true}}}); + {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = ReferenceCaching::Enabled}}}); CHECK_EQ(7, Zcs.GetBucketInfo(TearDrinkerBucket).value().DiskLayerInfo.EntryCount); GcResult Result = Gc.CollectGarbage(GcSettings{.CacheExpireTime = GcClock::Now() + std::chrono::hours(1), @@ -2051,7 +2084,7 @@ TEST_CASE("z$.newgc.basics") ZenCacheNamespace Zcs(Gc, *JobQueue, TempDir.Path() / "cache", - {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = true}}}); + {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = ReferenceCaching::Enabled}}}); CHECK_EQ(7, Zcs.GetBucketInfo(TearDrinkerBucket).value().DiskLayerInfo.EntryCount); GcResult Result = Gc.CollectGarbage(GcSettings{.CacheExpireTime = GcClock::Now() + std::chrono::hours(1), @@ -2086,7 +2119,7 @@ TEST_CASE("z$.newgc.basics") ZenCacheNamespace Zcs(Gc, *JobQueue, TempDir.Path() / "cache", - {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = true}}}); + {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = ReferenceCaching::Enabled}}}); CHECK_EQ(7, Zcs.GetBucketInfo(TearDrinkerBucket).value().DiskLayerInfo.EntryCount); GcResult Result = Gc.CollectGarbage(GcSettings{.CacheExpireTime = GcClock::Now() + std::chrono::hours(1), @@ -2121,7 +2154,7 @@ TEST_CASE("z$.newgc.basics") ZenCacheNamespace Zcs(Gc, *JobQueue, TempDir.Path() / "cache", - {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = true}}}); + {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = ReferenceCaching::Enabled}}}); CHECK_EQ(7, Zcs.GetBucketInfo(TearDrinkerBucket).value().DiskLayerInfo.EntryCount); GcResult Result = Gc.CollectGarbage(GcSettings{.CacheExpireTime = GcClock::Now() + std::chrono::hours(1), @@ -2162,7 +2195,7 @@ TEST_CASE("z$.newgc.basics") ZenCacheNamespace Zcs(Gc, *JobQueue, TempDir.Path() / "cache", - {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = true}}}); + {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = ReferenceCaching::Enabled}}}); CHECK_EQ(7, Zcs.GetBucketInfo(TearDrinkerBucket).value().DiskLayerInfo.EntryCount); GcResult Result = Gc.CollectGarbage(GcSettings{.CacheExpireTime = GcClock::Now() + std::chrono::hours(1), @@ -2198,7 +2231,7 @@ TEST_CASE("z$.newgc.basics") ZenCacheNamespace Zcs(Gc, *JobQueue, TempDir.Path() / "cache", - {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = true}}}); + {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = ReferenceCaching::Enabled}}}); CHECK_EQ(7, Zcs.GetBucketInfo(TearDrinkerBucket).value().DiskLayerInfo.EntryCount); Zcs.SetAccessTime(TearDrinkerBucket, CacheRecords[0], GcClock::Now() + std::chrono::hours(2)); @@ -2238,7 +2271,7 @@ TEST_CASE("z$.newgc.basics") ZenCacheNamespace Zcs(Gc, *JobQueue, TempDir.Path() / "cache", - {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = true}}}); + {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = ReferenceCaching::Enabled}}}); CHECK_EQ(7, Zcs.GetBucketInfo(TearDrinkerBucket).value().DiskLayerInfo.EntryCount); Zcs.SetAccessTime(TearDrinkerBucket, CacheRecords[0], GcClock::Now() + std::chrono::hours(2)); @@ -2277,7 +2310,7 @@ TEST_CASE("z$.newgc.basics") ZenCacheNamespace Zcs(Gc, *JobQueue, TempDir.Path() / "cache", - {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = true}}}); + {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = ReferenceCaching::Enabled}}}); CHECK_EQ(7, Zcs.GetBucketInfo(TearDrinkerBucket).value().DiskLayerInfo.EntryCount); Zcs.SetAccessTime(TearDrinkerBucket, UnstructuredCacheValues[1], GcClock::Now() + std::chrono::hours(2)); @@ -2317,7 +2350,7 @@ TEST_CASE("z$.newgc.basics") ZenCacheNamespace Zcs(Gc, *JobQueue, TempDir.Path() / "cache", - {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = true}}}); + {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = ReferenceCaching::Enabled}}}); CHECK_EQ(7, Zcs.GetBucketInfo(TearDrinkerBucket).value().DiskLayerInfo.EntryCount); // Prime so we can check GC of memory layer @@ -2370,7 +2403,7 @@ TEST_CASE("z$.newgc.basics") ZenCacheNamespace Zcs(Gc, *JobQueue, TempDir.Path() / "cache", - {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = true}}}); + {.DiskLayerConfig = {.BucketConfig = {.EnableReferenceCaching = ReferenceCaching::Enabled}}}); CHECK_EQ(7, Zcs.GetBucketInfo(TearDrinkerBucket).value().DiskLayerInfo.EntryCount); auto Attachments = -- cgit v1.2.3