diff options
| author | Stefan Boberg <[email protected]> | 2021-10-29 18:17:36 +0200 |
|---|---|---|
| committer | Stefan Boberg <[email protected]> | 2021-10-29 18:17:36 +0200 |
| commit | eff472457f4090a4476ced920cea2ea4cbeca7bf (patch) | |
| tree | cf7d0778af3babd411cdc9666dfd7c627780e159 /zenserver/cache/structuredcachestore.cpp | |
| parent | zenserver-test: Some modifications to avoid ODR violations (diff) | |
| download | zen-eff472457f4090a4476ced920cea2ea4cbeca7bf.tar.xz zen-eff472457f4090a4476ced920cea2ea4cbeca7bf.zip | |
z$: hooked up bucket traversal for gc
added some tests
added "test" mode for zenserver, to run any tests embedded in the zenserver (example: `zenserver test -tx=z$.*`)
Diffstat (limited to 'zenserver/cache/structuredcachestore.cpp')
| -rw-r--r-- | zenserver/cache/structuredcachestore.cpp | 128 |
1 files changed, 117 insertions, 11 deletions
diff --git a/zenserver/cache/structuredcachestore.cpp b/zenserver/cache/structuredcachestore.cpp index e7b840ed8..02ec43115 100644 --- a/zenserver/cache/structuredcachestore.cpp +++ b/zenserver/cache/structuredcachestore.cpp @@ -6,19 +6,27 @@ #include <zencore/windows.h> #include <zencore/compactbinary.h> +#include <zencore/compactbinarybuilder.h> +#include <zencore/compactbinarypackage.h> +#include <zencore/compactbinaryvalidation.h> +#include <zencore/compress.h> #include <zencore/filesystem.h> #include <zencore/fmtutils.h> #include <zencore/iobuffer.h> #include <zencore/logging.h> #include <zencore/string.h> +#include <zencore/testing.h> +#include <zencore/testutils.h> #include <zencore/thread.h> #include <zenstore/basicfile.h> #include <zenstore/cas.h> #include <zenstore/caslog.h> +#include <zenstore/cidstore.h> #include <concepts> #include <filesystem> #include <unordered_map> +#include <ranges> ZEN_THIRD_PARTY_INCLUDES_START #include <fmt/core.h> @@ -31,7 +39,7 @@ namespace zen { using namespace fmt::literals; -ZenCacheStore::ZenCacheStore(CasStore& Cas, const std::filesystem::path& RootDir) : m_DiskLayer{Cas, RootDir} +ZenCacheStore::ZenCacheStore(const std::filesystem::path& RootDir) : m_DiskLayer{RootDir} { ZEN_INFO("initializing structured cache at '{}'", RootDir); CreateDirectories(RootDir); @@ -125,7 +133,8 @@ ZenCacheStore::Scrub(ScrubContext& Ctx) void ZenCacheStore::GarbageCollect(GcContext& GcCtx) { - ZEN_UNUSED(GcCtx); + m_DiskLayer.GarbageCollect(GcCtx); + m_MemLayer.GarbageCollect(GcCtx); } ////////////////////////////////////////////////////////////////////////// @@ -213,7 +222,12 @@ ZenCacheMemoryLayer::Scrub(ScrubContext& Ctx) void ZenCacheMemoryLayer::GarbageCollect(GcContext& GcCtx) { - ZEN_UNUSED(GcCtx); + RwLock::SharedLockScope _(m_Lock); + + for (auto& Kv : m_Buckets) + { + Kv.second.GarbageCollect(GcCtx); + } } void @@ -358,7 +372,7 @@ static_assert(sizeof(DiskIndexEntry) == 36); struct ZenCacheDiskLayer::CacheBucket { - CacheBucket(CasStore& Cas); + CacheBucket(); ~CacheBucket(); void OpenOrCreate(std::filesystem::path BucketDir, bool AllowCreate = true); @@ -374,7 +388,6 @@ struct ZenCacheDiskLayer::CacheBucket inline bool IsOk() const { return m_IsOk; } private: - CasStore& m_CasStore; std::filesystem::path m_BucketDir; Oid m_BucketId; bool m_IsOk = false; @@ -405,7 +418,7 @@ private: inline RwLock& LockForHash(const IoHash& Hash) { return m_ShardedLocks[Hash.Hash[19]]; } }; -ZenCacheDiskLayer::CacheBucket::CacheBucket(CasStore& Cas) : m_CasStore(Cas) +ZenCacheDiskLayer::CacheBucket::CacheBucket() { } @@ -839,7 +852,7 @@ ZenCacheDiskLayer::CacheBucket::PutStandaloneCacheValue(const IoHash& HashKey, c ////////////////////////////////////////////////////////////////////////// -ZenCacheDiskLayer::ZenCacheDiskLayer(CasStore& Cas, const std::filesystem::path& RootDir) : m_RootDir(RootDir), m_CasStore(Cas) +ZenCacheDiskLayer::ZenCacheDiskLayer(const std::filesystem::path& RootDir) : m_RootDir(RootDir) { } @@ -873,7 +886,7 @@ ZenCacheDiskLayer::Get(std::string_view InBucket, const IoHash& HashKey, ZenCach } else { - auto It = m_Buckets.try_emplace(std::string(InBucket), m_CasStore); + auto It = m_Buckets.try_emplace(std::string(InBucket)); Bucket = &It.first->second; std::filesystem::path BucketPath = m_RootDir; @@ -916,7 +929,7 @@ ZenCacheDiskLayer::Put(std::string_view InBucket, const IoHash& HashKey, const Z } else { - auto It = m_Buckets.try_emplace(std::string(InBucket), m_CasStore); + auto It = m_Buckets.try_emplace(std::string(InBucket)); Bucket = &It.first->second; std::filesystem::path bucketPath = m_RootDir; @@ -972,7 +985,7 @@ ZenCacheDiskLayer::DiscoverBuckets() } else { - auto InsertResult = m_Buckets.try_emplace(BucketName8, m_CasStore); + auto InsertResult = m_Buckets.try_emplace(BucketName8); std::filesystem::path BucketPath = m_RootDir; BucketPath /= BucketName8; @@ -1050,7 +1063,100 @@ ZenCacheDiskLayer::Scrub(ScrubContext& Ctx) void ZenCacheDiskLayer::GarbageCollect(GcContext& GcCtx) { - ZEN_UNUSED(GcCtx); + RwLock::SharedLockScope _(m_Lock); + + for (auto& Kv : m_Buckets) + { + Kv.second.GarbageCollect(GcCtx); + } +} + +////////////////////////////////////////////////////////////////////////// + +#if ZEN_WITH_TESTS + +TEST_CASE("z$.store") +{ + using namespace fmt::literals; + using namespace std::literals; + + ScopedTemporaryDirectory TempDir; + + ZenCacheStore Zcs(TempDir.Path() / "cache"); + + const int kIterationCount = 100; + + for (int i = 0; i < kIterationCount; ++i) + { + const IoHash Key = IoHash::HashBuffer(&i, sizeof i); + + CbObjectWriter Cbo; + Cbo << "hey" << i; + CbObject Obj = Cbo.Save(); + + ZenCacheValue Value; + Value.Value = Obj.GetBuffer().AsIoBuffer(); + Value.Value.SetContentType(ZenContentType::kCbObject); + + Zcs.Put("test_bucket"sv, Key, Value); + } + + for (int i = 0; i < kIterationCount; ++i) + { + const IoHash Key = IoHash::HashBuffer(&i, sizeof i); + + ZenCacheValue Value; + Zcs.Get("test_bucket"sv, Key, /* out */ Value); + + REQUIRE(Value.Value); + CHECK(Value.Value.GetContentType() == ZenContentType::kCbObject); + CHECK_EQ(ValidateCompactBinary(Value.Value, CbValidateMode::All), CbValidateError::None); + CbObject Obj = LoadCompactBinaryObject(Value.Value); + CHECK_EQ(Obj["hey"].AsInt32(), i); + } +} + +TEST_CASE("z$.gc") +{ + using namespace fmt::literals; + using namespace std::literals; + + ScopedTemporaryDirectory TempDir; + + CasStoreConfiguration Config{.RootDirectory = TempDir.Path()}; + std::unique_ptr<CasStore> Cas{CreateCasStore()}; + Cas->Initialize(Config); + + CidStore Cid(*Cas, TempDir.Path()); + + ZenCacheStore Zcs(TempDir.Path() / "cache"); + + const int kIterationCount = 100; + + for (int i = 0; i < kIterationCount; ++i) + { + const IoHash Key = IoHash::HashBuffer(&i, sizeof i); + + CompressedBuffer CompBuf = CompressedBuffer::Compress(SharedBuffer::MakeView("abcd"sv)); + Cid.AddChunk(CompBuf); + + CbObjectWriter Cbo; + Cbo << "hey" << i << "ref" << CbAttachment(CompBuf); + CbObject Obj = Cbo.Save(); + + ZenCacheValue Value; + Value.Value = Obj.GetBuffer().AsIoBuffer(); + Value.Value.SetContentType(ZenContentType::kCbObject); + + Zcs.Put("test_bucket"sv, Key, Value); + } +} + +#endif + +void +z$_forcelink() +{ } } // namespace zen |