aboutsummaryrefslogtreecommitdiff
path: root/zenserver/cache/structuredcachestore.cpp
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2021-10-16 23:25:34 +0200
committerStefan Boberg <[email protected]>2021-10-16 23:25:34 +0200
commitf9803c0a42a74d51bdf184ec6486bcc470b26f55 (patch)
tree181c86087772398208ad3e22e55b625deb4e5bd6 /zenserver/cache/structuredcachestore.cpp
parentFixed up some more windows include issues (diff)
downloadzen-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.cpp113
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