aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2021-10-21 18:03:41 +0200
committerStefan Boberg <[email protected]>2021-10-21 18:03:41 +0200
commit3e824897aed32282ec9ee297e1cfc3efc5a8d251 (patch)
tree199d71e7314ecf7df577b4466f0d599b86c4dd08
parentAdded IsReady flag to ZenServerEntry (diff)
downloadzen-3e824897aed32282ec9ee297e1cfc3efc5a8d251.tar.xz
zen-3e824897aed32282ec9ee297e1cfc3efc5a8d251.zip
gc: Added GcStorage base class and hooked it up to CasGc
-rw-r--r--zen/chunk/chunk.cpp5
-rw-r--r--zenserver/cache/structuredcachestore.cpp18
-rw-r--r--zenserver/cache/structuredcachestore.h8
-rw-r--r--zenserver/zenserver.cpp4
-rw-r--r--zenstore/CAS.cpp15
-rw-r--r--zenstore/filecas.cpp16
-rw-r--r--zenstore/filecas.h7
-rw-r--r--zenstore/gc.cpp28
-rw-r--r--zenstore/include/zenstore/CAS.h3
-rw-r--r--zenstore/include/zenstore/gc.h27
10 files changed, 93 insertions, 38 deletions
diff --git a/zen/chunk/chunk.cpp b/zen/chunk/chunk.cpp
index 3283a8b66..043832dd3 100644
--- a/zen/chunk/chunk.cpp
+++ b/zen/chunk/chunk.cpp
@@ -15,6 +15,7 @@
#include <zencore/thread.h>
#include <zencore/timer.h>
#include <zenstore/cas.h>
+#include <zenstore/gc.h>
#include "../internalfile.h"
@@ -942,12 +943,14 @@ ChunkCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
std::unique_ptr<zen::CasStore> CasStore;
+ zen::CasGc Gc;
+
if (!m_RootDirectory.empty())
{
zen::CasStoreConfiguration Config;
Config.RootDirectory = m_RootDirectory;
- CasStore.reset(zen::CreateCasStore());
+ CasStore.reset(zen::CreateCasStore(Gc));
CasStore->Initialize(Config);
}
diff --git a/zenserver/cache/structuredcachestore.cpp b/zenserver/cache/structuredcachestore.cpp
index e28b2b2d8..f964c3102 100644
--- a/zenserver/cache/structuredcachestore.cpp
+++ b/zenserver/cache/structuredcachestore.cpp
@@ -145,10 +145,10 @@ ZenCacheStore::Scrub(ScrubContext& Ctx)
}
void
-ZenCacheStore::GarbageCollect(GcContext& GcCtx)
+ZenCacheStore::GatherReferences(GcContext& GcCtx)
{
- m_MemLayer.GarbageCollect(GcCtx);
- m_DiskLayer.GarbageCollect(GcCtx);
+ m_MemLayer.GatherReferences(GcCtx);
+ m_DiskLayer.GatherReferences(GcCtx);
}
//////////////////////////////////////////////////////////////////////////
@@ -234,7 +234,7 @@ ZenCacheMemoryLayer::Scrub(ScrubContext& Ctx)
}
void
-ZenCacheMemoryLayer::GarbageCollect(GcContext& GcCtx)
+ZenCacheMemoryLayer::GatherReferences(GcContext& GcCtx)
{
ZEN_UNUSED(GcCtx);
}
@@ -261,7 +261,7 @@ ZenCacheMemoryLayer::CacheBucket::Scrub(ScrubContext& Ctx)
}
void
-ZenCacheMemoryLayer::CacheBucket::GarbageCollect(GcContext& GcCtx)
+ZenCacheMemoryLayer::CacheBucket::GatherReferences(GcContext& GcCtx)
{
// Is it even meaningful to do this? The memory layer shouldn't
// contain anything which is not already in the disk layer
@@ -391,7 +391,7 @@ struct ZenCacheDiskLayer::CacheBucket
void Drop();
void Flush();
void Scrub(ScrubContext& Ctx);
- void GarbageCollect(GcContext& GcCtx);
+ void GatherReferences(GcContext& GcCtx);
inline bool IsOk() const { return m_IsOk; }
@@ -723,7 +723,7 @@ ZenCacheDiskLayer::CacheBucket::Scrub(ScrubContext& Ctx)
}
void
-ZenCacheDiskLayer::CacheBucket::GarbageCollect(GcContext& GcCtx)
+ZenCacheDiskLayer::CacheBucket::GatherReferences(GcContext& GcCtx)
{
RwLock::SharedLockScope _(m_IndexLock);
@@ -1069,13 +1069,13 @@ ZenCacheDiskLayer::Scrub(ScrubContext& Ctx)
}
void
-ZenCacheDiskLayer::GarbageCollect(GcContext& GcCtx)
+ZenCacheDiskLayer::GatherReferences(GcContext& GcCtx)
{
RwLock::SharedLockScope _(m_Lock);
for (auto& Kv : m_Buckets)
{
- Kv.second.GarbageCollect(GcCtx);
+ Kv.second.GatherReferences(GcCtx);
}
}
diff --git a/zenserver/cache/structuredcachestore.h b/zenserver/cache/structuredcachestore.h
index 042d2ab3d..cf22b8be2 100644
--- a/zenserver/cache/structuredcachestore.h
+++ b/zenserver/cache/structuredcachestore.h
@@ -66,7 +66,7 @@ public:
void Put(std::string_view Bucket, const IoHash& HashKey, const ZenCacheValue& Value);
bool DropBucket(std::string_view Bucket);
void Scrub(ScrubContext& Ctx);
- void GarbageCollect(GcContext& GcCtx);
+ void GatherReferences(GcContext& GcCtx);
struct Configuration
{
@@ -92,7 +92,7 @@ private:
bool Get(const IoHash& HashKey, ZenCacheValue& OutValue);
void Put(const IoHash& HashKey, const ZenCacheValue& Value);
void Scrub(ScrubContext& Ctx);
- void GarbageCollect(GcContext& GcCtx);
+ void GatherReferences(GcContext& GcCtx);
private:
uint64_t GetCurrentTimeStamp();
@@ -114,7 +114,7 @@ public:
bool DropBucket(std::string_view Bucket);
void Flush();
void Scrub(ScrubContext& Ctx);
- void GarbageCollect(GcContext& GcCtx);
+ void GatherReferences(GcContext& GcCtx);
void DiscoverBuckets();
@@ -140,7 +140,7 @@ public:
bool DropBucket(std::string_view Bucket);
void Flush();
void Scrub(ScrubContext& Ctx);
- virtual void GarbageCollect(GcContext& GcCtx) override;
+ virtual void GatherReferences(GcContext& GcCtx) override;
private:
std::filesystem::path m_RootDir;
diff --git a/zenserver/zenserver.cpp b/zenserver/zenserver.cpp
index c96fec986..4e9d2f644 100644
--- a/zenserver/zenserver.cpp
+++ b/zenserver/zenserver.cpp
@@ -472,8 +472,8 @@ private:
zen::Ref<zen::HttpServer> m_Http;
zen::HttpStatusService m_StatusService;
zen::HttpStatsService m_StatsService;
- std::unique_ptr<zen::CasStore> m_CasStore{zen::CreateCasStore()};
- zen::CasGc m_Gc{*m_CasStore};
+ zen::CasGc m_Gc;
+ std::unique_ptr<zen::CasStore> m_CasStore{zen::CreateCasStore(m_Gc)};
std::unique_ptr<zen::CidStore> m_CidStore;
std::unique_ptr<zen::ZenCacheStore> m_CacheStore;
zen::CasScrubber m_Scrubber{*m_CasStore};
diff --git a/zenstore/CAS.cpp b/zenstore/CAS.cpp
index 20ad20971..09e13a702 100644
--- a/zenstore/CAS.cpp
+++ b/zenstore/CAS.cpp
@@ -17,6 +17,7 @@
#include <zencore/testutils.h>
#include <zencore/thread.h>
#include <zencore/uid.h>
+#include <zenstore/gc.h>
#include <gsl/gsl-lite.hpp>
@@ -94,7 +95,7 @@ ScrubContext::ReportScrubbed(uint64_t ChunkCount, uint64_t ChunkBytes)
class CasImpl : public CasStore
{
public:
- CasImpl();
+ CasImpl(CasGc& Gc);
virtual ~CasImpl();
virtual void Initialize(const CasStoreConfiguration& InConfig) override;
@@ -123,7 +124,7 @@ private:
void UpdateManifest(bool IsNewStore);
};
-CasImpl::CasImpl() : m_TinyStrategy(m_Config), m_SmallStrategy(m_Config), m_LargeStrategy(m_Config)
+CasImpl::CasImpl(CasGc& Gc) : m_TinyStrategy(m_Config), m_SmallStrategy(m_Config), m_LargeStrategy(m_Config, Gc)
{
}
@@ -313,15 +314,15 @@ CasImpl::Scrub(ScrubContext& Ctx)
void
CasImpl::GarbageCollect(GcContext& GcCtx)
{
- m_LargeStrategy.GarbageCollect(GcCtx);
+ m_LargeStrategy.CollectGarbage(GcCtx);
}
//////////////////////////////////////////////////////////////////////////
CasStore*
-CreateCasStore()
+CreateCasStore(CasGc& Gc)
{
- return new CasImpl();
+ return new CasImpl(Gc);
}
//////////////////////////////////////////////////////////////////////////
@@ -338,7 +339,9 @@ TEST_CASE("CasStore")
CasStoreConfiguration config;
config.RootDirectory = TempDir.Path();
- std::unique_ptr<CasStore> Store{CreateCasStore()};
+ CasGc Gc;
+
+ std::unique_ptr<CasStore> Store{CreateCasStore(Gc)};
Store->Initialize(config);
ScrubContext Ctx;
diff --git a/zenstore/filecas.cpp b/zenstore/filecas.cpp
index d8811de00..9cb6e5c79 100644
--- a/zenstore/filecas.cpp
+++ b/zenstore/filecas.cpp
@@ -14,10 +14,10 @@
#include <zencore/thread.h>
#include <zencore/uid.h>
#include <zenstore/basicfile.h>
+#include <zenstore/gc.h>
#if ZEN_WITH_TESTS
# include <zencore/compactbinarybuilder.h>
-# include <zenstore/gc.h>
#endif
#include <gsl/gsl-lite.hpp>
@@ -70,7 +70,7 @@ FileCasStrategy::ShardingHelper::ShardingHelper(const std::filesystem::path& Roo
//////////////////////////////////////////////////////////////////////////
-FileCasStrategy::FileCasStrategy(const CasStoreConfiguration& Config) : m_Config(Config), m_Log(logging::Get("filecas"))
+FileCasStrategy::FileCasStrategy(const CasStoreConfiguration& Config, CasGc& Gc) : GcStorage(Gc), m_Config(Config), m_Log(logging::Get("filecas"))
{
}
@@ -481,7 +481,7 @@ FileCasStrategy::Scrub(ScrubContext& Ctx)
}
void
-FileCasStrategy::GarbageCollect(GcContext& GcCtx)
+FileCasStrategy::CollectGarbage(GcContext& GcCtx)
{
ZEN_UNUSED(GcCtx);
}
@@ -497,10 +497,12 @@ TEST_CASE("cas.file.move")
// specifying an absolute path here can be helpful when using procmon to dig into things
ScopedTemporaryDirectory TempDir; // {"d:\\filecas_testdir"};
+ CasGc Gc;
+
CasStoreConfiguration CasConfig;
CasConfig.RootDirectory = TempDir.Path() / "cas";
- FileCasStrategy FileCas(CasConfig);
+ FileCasStrategy FileCas(CasConfig, Gc);
{
std::filesystem::path Payload1Path{TempDir.Path() / "payload_1"};
@@ -575,10 +577,12 @@ TEST_CASE("cas.file.gc")
// specifying an absolute path here can be helpful when using procmon to dig into things
ScopedTemporaryDirectory TempDir; // {"d:\\filecas_testdir"};
+ CasGc Gc;
+
CasStoreConfiguration CasConfig;
CasConfig.RootDirectory = TempDir.Path() / "cas";
- FileCasStrategy FileCas(CasConfig);
+ FileCasStrategy FileCas(CasConfig, Gc);
for (int i = 0; i < 1000; ++i)
{
@@ -595,7 +599,7 @@ TEST_CASE("cas.file.gc")
GcContext Ctx;
- FileCas.GarbageCollect(Ctx);
+ FileCas.CollectGarbage(Ctx);
}
#endif
diff --git a/zenstore/filecas.h b/zenstore/filecas.h
index 14314ce52..bbba9733e 100644
--- a/zenstore/filecas.h
+++ b/zenstore/filecas.h
@@ -9,6 +9,7 @@
#include <zencore/string.h>
#include <zencore/thread.h>
#include <zenstore/cas.h>
+#include <zenstore/gc.h>
#include <functional>
@@ -23,9 +24,9 @@ class BasicFile;
/** CAS storage strategy using a file-per-chunk storage strategy
*/
-struct FileCasStrategy
+struct FileCasStrategy : public GcStorage
{
- FileCasStrategy(const CasStoreConfiguration& Config);
+ FileCasStrategy(const CasStoreConfiguration& Config, CasGc& Gc);
~FileCasStrategy();
CasStore::InsertResult InsertChunk(const void* ChunkData, size_t ChunkSize, const IoHash& ChunkHash);
@@ -34,7 +35,7 @@ struct FileCasStrategy
bool HaveChunk(const IoHash& ChunkHash);
void FilterChunks(CasChunkSet& InOutChunks);
void Flush();
- void GarbageCollect(GcContext& GcCtx);
+ virtual void CollectGarbage(GcContext& GcCtx) override;
void Scrub(ScrubContext& Ctx);
private:
diff --git a/zenstore/gc.cpp b/zenstore/gc.cpp
index 612cceed9..79c646db2 100644
--- a/zenstore/gc.cpp
+++ b/zenstore/gc.cpp
@@ -47,7 +47,19 @@ GcContributor::~GcContributor()
//////////////////////////////////////////////////////////////////////////
-CasGc::CasGc(CasStore& Store) : m_CasStore(Store)
+GcStorage::GcStorage(CasGc& Gc) : m_Gc(Gc)
+{
+ m_Gc.AddGcStorage(this);
+}
+
+GcStorage::~GcStorage()
+{
+ m_Gc.AddGcStorage(this);
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+CasGc::CasGc()
{
}
@@ -70,6 +82,20 @@ CasGc::RemoveGcContributor(GcContributor* Contributor)
}
void
+CasGc::AddGcStorage(GcStorage* Storage)
+{
+ RwLock::ExclusiveLockScope _(m_Lock);
+ m_GcStorage.push_back(Storage);
+}
+
+void
+CasGc::RemoveGcStorage(GcStorage* Storage)
+{
+ RwLock::ExclusiveLockScope _(m_Lock);
+ std::erase_if(m_GcStorage, [&](GcStorage* $) { return $ == Storage; });
+}
+
+void
CasGc::CollectGarbage()
{
}
diff --git a/zenstore/include/zenstore/CAS.h b/zenstore/include/zenstore/CAS.h
index 738103f73..a387b905e 100644
--- a/zenstore/include/zenstore/CAS.h
+++ b/zenstore/include/zenstore/CAS.h
@@ -20,6 +20,7 @@
namespace zen {
class GcContext;
+class CasGc;
struct CasStoreConfiguration
{
@@ -107,7 +108,7 @@ protected:
uint64_t m_LastScrubTime = 0;
};
-ZENCORE_API CasStore* CreateCasStore();
+ZENCORE_API CasStore* CreateCasStore(CasGc& Gc);
void CAS_forcelink();
diff --git a/zenstore/include/zenstore/gc.h b/zenstore/include/zenstore/gc.h
index 942355293..d51925a0c 100644
--- a/zenstore/include/zenstore/gc.h
+++ b/zenstore/include/zenstore/gc.h
@@ -33,10 +33,9 @@ private:
std::unique_ptr<GcState> m_State;
};
-
/** GC root contributor
- Higher level data structures provide roots for the garbage collector,
+ Higher level data structures provide roots for the garbage collector,
which ultimately determine what is garbage and what data we need to
retain.
@@ -48,24 +47,42 @@ public:
GcContributor(CasGc& Gc);
~GcContributor();
- virtual void GarbageCollect(GcContext& GcCtx) = 0;
+ virtual void GatherReferences(GcContext& GcCtx) = 0;
protected:
CasGc& m_Gc;
};
+/** GC storage provider
+ */
+
+class GcStorage
+{
+public:
+ GcStorage(CasGc& Gc);
+ ~GcStorage();
+
+ virtual void CollectGarbage(GcContext& GcCtrx) = 0;
+
+private:
+ CasGc& m_Gc;
+};
+
/** GC orchestrator
*/
class CasGc
{
public:
- CasGc(CasStore& Store);
+ CasGc();
~CasGc();
void AddGcContributor(GcContributor* Contributor);
void RemoveGcContributor(GcContributor* Contributor);
+ void AddGcStorage(GcStorage* Contributor);
+ void RemoveGcStorage(GcStorage* Contributor);
+
void CollectGarbage();
void OnNewCidReferences(std::span<IoHash> Hashes);
@@ -73,9 +90,9 @@ public:
void OnDroppedCidReferences(std::span<IoHash> Hashes);
private:
- CasStore& m_CasStore;
RwLock m_Lock;
std::vector<GcContributor*> m_GcContribs;
+ std::vector<GcStorage*> m_GcStorage;
};
} // namespace zen