diff options
Diffstat (limited to 'zenstore')
| -rw-r--r-- | zenstore/CAS.cpp | 15 | ||||
| -rw-r--r-- | zenstore/filecas.cpp | 16 | ||||
| -rw-r--r-- | zenstore/filecas.h | 7 | ||||
| -rw-r--r-- | zenstore/gc.cpp | 28 | ||||
| -rw-r--r-- | zenstore/include/zenstore/CAS.h | 3 | ||||
| -rw-r--r-- | zenstore/include/zenstore/gc.h | 27 |
6 files changed, 74 insertions, 22 deletions
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 |