diff options
| author | Per Larsson <[email protected]> | 2021-12-13 14:01:04 +0100 |
|---|---|---|
| committer | Per Larsson <[email protected]> | 2021-12-13 14:01:04 +0100 |
| commit | 4c58cfb3540bb64fd7fae72f1550b5b8d22d6878 (patch) | |
| tree | 694a342308e47a8ad3e9610b03b434e71ec6d949 | |
| parent | Merge branch 'main' into gc (diff) | |
| download | zen-4c58cfb3540bb64fd7fae72f1550b5b8d22d6878.tar.xz zen-4c58cfb3540bb64fd7fae72f1550b5b8d22d6878.zip | |
Fixed bug in z$ GC.
| -rw-r--r-- | zenserver/cache/structuredcachestore.cpp | 70 | ||||
| -rw-r--r-- | zenstore/gc.cpp | 37 | ||||
| -rw-r--r-- | zenstore/include/zenstore/gc.h | 6 |
3 files changed, 61 insertions, 52 deletions
diff --git a/zenserver/cache/structuredcachestore.cpp b/zenserver/cache/structuredcachestore.cpp index 030588659..44c7b728b 100644 --- a/zenserver/cache/structuredcachestore.cpp +++ b/zenserver/cache/structuredcachestore.cpp @@ -444,7 +444,7 @@ static_assert(sizeof(DiskIndexEntry) == 36); struct ZenCacheDiskLayer::CacheBucket { - CacheBucket(); + CacheBucket(std::string BucketName); ~CacheBucket(); void OpenOrCreate(std::filesystem::path BucketDir, bool AllowCreate = true); @@ -463,6 +463,7 @@ struct ZenCacheDiskLayer::CacheBucket inline uint64_t TotalSize() const { return m_TotalSize.load(std::memory_order::relaxed); } private: + std::string m_BucketName; std::filesystem::path m_BucketDir; Oid m_BucketId; bool m_IsOk = false; @@ -504,7 +505,7 @@ private: inline RwLock& LockForHash(const IoHash& Hash) { return m_ShardedLocks[Hash.Hash[19]]; } }; -ZenCacheDiskLayer::CacheBucket::CacheBucket() +ZenCacheDiskLayer::CacheBucket::CacheBucket(std::string BucketName) : m_BucketName(std::move(BucketName)) { } @@ -916,7 +917,7 @@ ZenCacheDiskLayer::CacheBucket::GatherReferences(GcContext& GcCtx) std::transform(Entries.begin(), ValidIt, std::back_inserter(ExpiredKeys), [](const auto& Kv) { return Kv.first; }); GcCtx.ContributeCids(Cids); - GcCtx.ContributeCacheKeys(std::move(ValidKeys), std::move(ExpiredKeys)); + GcCtx.ContributeCacheKeys(m_BucketName, std::move(ValidKeys), std::move(ExpiredKeys)); } void @@ -963,8 +964,8 @@ ZenCacheDiskLayer::CacheBucket::CollectGarbage(GcContext& GcCtx) std::vector<IndexMap::value_type> ValidEntries; std::vector<IndexMap::value_type> ExpiredEntries; - AddEntries(GcCtx.ValidCacheKeys(), ValidEntries); - AddEntries(GcCtx.ExpiredCacheKeys(), ExpiredEntries); + AddEntries(GcCtx.ValidCacheKeys(m_BucketName), ValidEntries); + AddEntries(GcCtx.ExpiredCacheKeys(m_BucketName), ExpiredEntries); // Remove all standalone file(s) // NOTE: This can probably be made asynchronously @@ -1268,12 +1269,13 @@ ZenCacheDiskLayer::~ZenCacheDiskLayer() = default; bool ZenCacheDiskLayer::Get(std::string_view InBucket, const IoHash& HashKey, ZenCacheValue& OutValue) { - CacheBucket* Bucket = nullptr; + const auto BucketName = std::string(InBucket); + CacheBucket* Bucket = nullptr; { RwLock::SharedLockScope _(m_Lock); - auto it = m_Buckets.find(std::string(InBucket)); + auto it = m_Buckets.find(BucketName); if (it != m_Buckets.end()) { @@ -1287,17 +1289,17 @@ ZenCacheDiskLayer::Get(std::string_view InBucket, const IoHash& HashKey, ZenCach RwLock::ExclusiveLockScope _(m_Lock); - if (auto it = m_Buckets.find(std::string(InBucket)); it != m_Buckets.end()) + if (auto it = m_Buckets.find(BucketName); it != m_Buckets.end()) { Bucket = &it->second; } else { - auto It = m_Buckets.try_emplace(std::string(InBucket)); + auto It = m_Buckets.try_emplace(BucketName, BucketName); Bucket = &It.first->second; std::filesystem::path BucketPath = m_RootDir; - BucketPath /= std::string(InBucket); + BucketPath /= BucketName; Bucket->OpenOrCreate(BucketPath); } @@ -1311,12 +1313,13 @@ ZenCacheDiskLayer::Get(std::string_view InBucket, const IoHash& HashKey, ZenCach void ZenCacheDiskLayer::Put(std::string_view InBucket, const IoHash& HashKey, const ZenCacheValue& Value) { - CacheBucket* Bucket = nullptr; + const auto BucketName = std::string(InBucket); + CacheBucket* Bucket = nullptr; { RwLock::SharedLockScope _(m_Lock); - auto it = m_Buckets.find(std::string(InBucket)); + auto it = m_Buckets.find(BucketName); if (it != m_Buckets.end()) { @@ -1330,17 +1333,17 @@ ZenCacheDiskLayer::Put(std::string_view InBucket, const IoHash& HashKey, const Z RwLock::ExclusiveLockScope _(m_Lock); - if (auto it = m_Buckets.find(std::string(InBucket)); it != m_Buckets.end()) + if (auto it = m_Buckets.find(BucketName); it != m_Buckets.end()) { Bucket = &it->second; } else { - auto It = m_Buckets.try_emplace(std::string(InBucket)); + auto It = m_Buckets.try_emplace(BucketName, BucketName); Bucket = &It.first->second; std::filesystem::path bucketPath = m_RootDir; - bucketPath /= std::string(InBucket); + bucketPath /= BucketName; Bucket->OpenOrCreate(bucketPath); } @@ -1392,7 +1395,7 @@ ZenCacheDiskLayer::DiscoverBuckets() } else { - auto InsertResult = m_Buckets.try_emplace(BucketName8); + auto InsertResult = m_Buckets.try_emplace(BucketName8, BucketName8); std::filesystem::path BucketPath = m_RootDir; BucketPath /= BucketName8; @@ -1504,7 +1507,6 @@ using namespace std::literals; using namespace fmt::literals; namespace testutils { - IoHash CreateKey(size_t KeyValue) { return IoHash::HashBuffer(&KeyValue, sizeof(size_t)); } IoBuffer CreateBinaryCacheValue(uint64_t Size) @@ -1715,23 +1717,23 @@ TEST_CASE("z$.gc") } // Expect timestamps to be serialized - //{ - // CasGc Gc; - // ZenCacheStore Zcs(Gc, TempDir.Path() / "cache"); - // std::vector<IoHash> Keep; - - // // Collect garbage with 1 hour max cache duration - // { - // CollectAndFilter(Gc, GcClock::Now(), std::chrono::hours(1), Cids, Keep); - // CHECK_EQ(3, Keep.size()); - // } - - // // Move forward in time - // { - // CollectAndFilter(Gc, GcClock::Now() + std::chrono::hours(2), std::chrono::hours(1), Cids, Keep); - // CHECK_EQ(0, Keep.size()); - // } - //} + { + CasGc Gc; + ZenCacheStore Zcs(Gc, TempDir.Path() / "cache"); + std::vector<IoHash> Keep; + + // Collect garbage with 1 hour max cache duration + { + CollectAndFilter(Gc, GcClock::Now(), std::chrono::hours(1), Cids, Keep); + CHECK_EQ(3, Keep.size()); + } + + // Move forward in time + { + CollectAndFilter(Gc, GcClock::Now() + std::chrono::hours(2), std::chrono::hours(1), Cids, Keep); + CHECK_EQ(0, Keep.size()); + } + } } SUBCASE("gc removes standalone values") diff --git a/zenstore/gc.cpp b/zenstore/gc.cpp index 676374167..bb26af87b 100644 --- a/zenstore/gc.cpp +++ b/zenstore/gc.cpp @@ -50,14 +50,21 @@ SaveCompactBinaryObject(const fs::path& Path, const CbObject& Object) struct GcContext::GcState { - CasChunkSet m_CasChunks; - CasChunkSet m_CidChunks; - std::vector<IoHash> m_ValidCacheKeys; - std::vector<IoHash> m_ExpiredCacheKeys; - GcClock::TimePoint m_GcTime; - GcClock::Duration m_MaxCacheDuration = std::chrono::hours(24); - bool m_DeletionMode = true; - bool m_CollectSmallObjects = false; + struct CacheBucket + { + std::vector<IoHash> ValidKeys; + std::vector<IoHash> ExpiredKeys; + }; + + using CacheBuckets = std::unordered_map<std::string, CacheBucket>; + + CacheBuckets m_CacheBuckets; + CasChunkSet m_CasChunks; + CasChunkSet m_CidChunks; + GcClock::TimePoint m_GcTime; + GcClock::Duration m_MaxCacheDuration = std::chrono::hours(24); + bool m_DeletionMode = true; + bool m_CollectSmallObjects = false; }; GcContext::GcContext(GcClock::TimePoint Time) : m_State(std::make_unique<GcState>()) @@ -82,10 +89,10 @@ GcContext::ContributeCas(std::span<const IoHash> Cas) } void -GcContext::ContributeCacheKeys(std::vector<IoHash> ValidKeys, std::vector<IoHash> ExpiredKeys) +GcContext::ContributeCacheKeys(const std::string& Bucket, std::vector<IoHash> ValidKeys, std::vector<IoHash> ExpiredKeys) { - m_State->m_ValidCacheKeys = std::move(ValidKeys); - m_State->m_ExpiredCacheKeys = std::move(ExpiredKeys); + m_State->m_CacheBuckets[Bucket].ValidKeys = std::move(ValidKeys); + m_State->m_CacheBuckets[Bucket].ExpiredKeys = std::move(ExpiredKeys); } void @@ -107,15 +114,15 @@ GcContext::FilterCas(std::span<const IoHash> Cas, std::function<void(const IoHas } std::span<const IoHash> -GcContext::ValidCacheKeys() const +GcContext::ValidCacheKeys(const std::string& Bucket) const { - return m_State->m_ValidCacheKeys; + return m_State->m_CacheBuckets[Bucket].ValidKeys; } std::span<const IoHash> -GcContext::ExpiredCacheKeys() const +GcContext::ExpiredCacheKeys(const std::string& Bucket) const { - return m_State->m_ExpiredCacheKeys; + return m_State->m_CacheBuckets[Bucket].ExpiredKeys; } bool diff --git a/zenstore/include/zenstore/gc.h b/zenstore/include/zenstore/gc.h index 995453d47..fe93456c6 100644 --- a/zenstore/include/zenstore/gc.h +++ b/zenstore/include/zenstore/gc.h @@ -51,15 +51,15 @@ public: void ContributeCids(std::span<const IoHash> Cid); void ContributeCas(std::span<const IoHash> Hash); - void ContributeCacheKeys(std::vector<IoHash> ValidKeys, std::vector<IoHash> ExpiredKeys); + void ContributeCacheKeys(const std::string& Bucket, std::vector<IoHash> ValidKeys, std::vector<IoHash> ExpiredKeys); void IterateCids(std::function<void(const IoHash&)> Callback); void FilterCids(std::span<const IoHash> Cid, std::function<void(const IoHash&)> KeepFunc); void FilterCas(std::span<const IoHash> Cas, std::function<void(const IoHash&)> KeepFunc); - std::span<const IoHash> ValidCacheKeys() const; - std::span<const IoHash> ExpiredCacheKeys() const; + std::span<const IoHash> ValidCacheKeys(const std::string& Bucket) const; + std::span<const IoHash> ExpiredCacheKeys(const std::string& Bucket) const; bool IsDeletionMode() const; void SetDeletionMode(bool NewState); |