diff options
| author | Stefan Boberg <[email protected]> | 2021-10-16 23:25:34 +0200 |
|---|---|---|
| committer | Stefan Boberg <[email protected]> | 2021-10-16 23:25:34 +0200 |
| commit | f9803c0a42a74d51bdf184ec6486bcc470b26f55 (patch) | |
| tree | 181c86087772398208ad3e22e55b625deb4e5bd6 /zenserver/cache/structuredcachestore.cpp | |
| parent | Fixed up some more windows include issues (diff) | |
| download | zen-f9803c0a42a74d51bdf184ec6486bcc470b26f55.tar.xz zen-f9803c0a42a74d51bdf184ec6486bcc470b26f55.zip | |
structured cache: Implemented GarbageCollect() for disk and memory buckets
Diffstat (limited to 'zenserver/cache/structuredcachestore.cpp')
| -rw-r--r-- | zenserver/cache/structuredcachestore.cpp | 113 |
1 files changed, 87 insertions, 26 deletions
diff --git a/zenserver/cache/structuredcachestore.cpp b/zenserver/cache/structuredcachestore.cpp index fcd10bdac..e7b840ed8 100644 --- a/zenserver/cache/structuredcachestore.cpp +++ b/zenserver/cache/structuredcachestore.cpp @@ -16,12 +16,15 @@ #include <zenstore/cas.h> #include <zenstore/caslog.h> -#include <fmt/core.h> #include <concepts> #include <filesystem> -#include <gsl/gsl-lite.hpp> #include <unordered_map> +ZEN_THIRD_PARTY_INCLUDES_START +#include <fmt/core.h> +#include <gsl/gsl-lite.hpp> +ZEN_THIRD_PARTY_INCLUDES_END + ////////////////////////////////////////////////////////////////////////// namespace zen { @@ -237,7 +240,31 @@ ZenCacheMemoryLayer::CacheBucket::Scrub(ScrubContext& Ctx) void ZenCacheMemoryLayer::CacheBucket::GarbageCollect(GcContext& GcCtx) { - ZEN_UNUSED(GcCtx); + // Is it even meaningful to do this? The memory layer shouldn't + // contain anything which is not already in the disk layer + + RwLock::SharedLockScope _(m_bucketLock); + + std::vector<IoHash> BadHashes; + + for (const auto& Kv : m_cacheMap) + { + const IoBuffer& Payload = Kv.second.Payload; + + switch (Payload.GetContentType()) + { + case ZenContentType::kCbObject: + { + CbObject Obj(SharedBuffer{Payload}); + + Obj.IterateAttachments([&](CbFieldView Field) { GcCtx.ContributeCids(std::array<IoHash, 1>{Field.AsAttachment()}); }); + } + break; + + case ZenContentType::kBinary: + break; + } + } } bool @@ -294,6 +321,7 @@ struct DiskLocation static const uint64_t kFlagsMask = 0xff00'0000'0000'0000ull; static const uint64_t kStandaloneFile = 0x8000'0000'0000'0000ull; static const uint64_t kStructured = 0x4000'0000'0000'0000ull; + static const uint64_t kTombStone = 0x2000'0000'0000'0000ull; static uint64_t CombineOffsetAndFlags(uint64_t Offset, uint64_t Flags) { return Offset | Flags; } @@ -625,9 +653,7 @@ ZenCacheDiskLayer::CacheBucket::Flush() void ZenCacheDiskLayer::CacheBucket::Scrub(ScrubContext& Ctx) { - std::atomic<uint64_t> ScrubbedChunks{0}, ScrubbedBytes{0}; - - std::vector<IoHash> BadChunks; + std::vector<IoHash> BadKeys; { RwLock::SharedLockScope _(m_IndexLock); @@ -643,44 +669,79 @@ ZenCacheDiskLayer::CacheBucket::Scrub(ScrubContext& Ctx) { // Validate contents } + else if (GetStandaloneCacheValue(Loc, HashKey, Value)) + { + // Note: we cannot currently validate contents since we don't + // have a content hash! + } else { - if (Loc.IsFlagSet(DiskLocation::kStandaloneFile)) - { - if (GetStandaloneCacheValue(Loc, HashKey, Value)) - { - // Note: we cannot currently validate contents since we don't - // have a content hash! - } - else - { - // Value not found - BadChunks.push_back(HashKey); - } - } + // Value not found + BadKeys.push_back(HashKey); } } } - Ctx.ReportScrubbed(ScrubbedChunks, ScrubbedBytes); - - if (BadChunks.empty()) + if (BadKeys.empty()) { return; } - Ctx.ReportBadCasChunks(BadChunks); - if (Ctx.RunRecovery()) { - // Clean out bad data + RwLock::ExclusiveLockScope _(m_IndexLock); + + for (const IoHash& BadKey : BadKeys) + { + // Log a tombstone and delete the in-memory index for the bad entry + + m_SlogFile.Append(DiskIndexEntry{.Key = BadKey, .Location = {0, 0, 0, DiskLocation::kTombStone}}); + m_Index.erase(BadKey); + } } } void ZenCacheDiskLayer::CacheBucket::GarbageCollect(GcContext& GcCtx) { - ZEN_UNUSED(GcCtx); + RwLock::SharedLockScope _(m_IndexLock); + + for (auto& Kv : m_Index) + { + const IoHash& HashKey = Kv.first; + const DiskLocation& Loc = Kv.second; + + if (Loc.IsFlagSet(DiskLocation::kStructured) == false) + { + continue; + } + + ZenCacheValue CacheValue; + std::vector<IoHash> Attachments; + + auto GatherRefs = [&] { + ZEN_ASSERT(CacheValue.Value.GetContentType() == ZenContentType::kCbObject); + + CbObject Obj(SharedBuffer{CacheValue.Value}); + Obj.IterateAttachments([&](CbFieldView Field) { Attachments.push_back(Field.AsAttachment()); }); + GcCtx.ContributeCids(Attachments); + }; + + if (GetInlineCacheValue(Loc, /* out */ CacheValue)) + { + GatherRefs(); + } + else if (GetStandaloneCacheValue(Loc, HashKey, /* out */ CacheValue)) + { + GatherRefs(); + } + else + { + // Value not found + } + + GcCtx.ContributeCids(Attachments); + } } void |