aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPer Larsson <[email protected]>2021-12-13 14:01:04 +0100
committerPer Larsson <[email protected]>2021-12-13 14:01:04 +0100
commit4c58cfb3540bb64fd7fae72f1550b5b8d22d6878 (patch)
tree694a342308e47a8ad3e9610b03b434e71ec6d949
parentMerge branch 'main' into gc (diff)
downloadzen-4c58cfb3540bb64fd7fae72f1550b5b8d22d6878.tar.xz
zen-4c58cfb3540bb64fd7fae72f1550b5b8d22d6878.zip
Fixed bug in z$ GC.
-rw-r--r--zenserver/cache/structuredcachestore.cpp70
-rw-r--r--zenstore/gc.cpp37
-rw-r--r--zenstore/include/zenstore/gc.h6
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);