aboutsummaryrefslogtreecommitdiff
path: root/zenstore/gc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'zenstore/gc.cpp')
-rw-r--r--zenstore/gc.cpp183
1 files changed, 181 insertions, 2 deletions
diff --git a/zenstore/gc.cpp b/zenstore/gc.cpp
index bfb8f015e..278f09b0b 100644
--- a/zenstore/gc.cpp
+++ b/zenstore/gc.cpp
@@ -2,9 +2,97 @@
#include <zenstore/gc.h>
+#include <zenstore/CAS.h>
+#include <zenstore/cidstore.h>
+#include <zencore/logging.h>
+
namespace zen {
-CasGc::CasGc(CasStore& Store) : m_CasStore(Store)
+//////////////////////////////////////////////////////////////////////////
+
+struct GcContext::GcState
+{
+ CasChunkSet m_CasChunks;
+ CasChunkSet m_CidChunks;
+ bool m_DeletionMode = true;
+};
+
+GcContext::GcContext() : m_State(std::make_unique<GcState>())
+{
+}
+
+GcContext::~GcContext()
+{
+}
+
+void
+GcContext::ContributeCids(std::span<const IoHash> Cids)
+{
+ m_State->m_CidChunks.AddChunksToSet(Cids);
+}
+
+void
+GcContext::ContributeCas(std::span<const IoHash> Cas)
+{
+ m_State->m_CasChunks.AddChunksToSet(Cas);
+}
+
+void
+GcContext::IterateCids(std::function<void(const IoHash&)> Callback)
+{
+ m_State->m_CidChunks.IterateChunks([&](const IoHash& Hash) { Callback(Hash); });
+}
+
+void
+GcContext::FilterCids(std::span<const IoHash> Cid, std::function<void(const IoHash&)> KeepFunc)
+{
+ m_State->m_CidChunks.FilterChunks(Cid, [&](const IoHash& Hash) { KeepFunc(Hash); });
+}
+
+void
+GcContext::FilterCas(std::span<const IoHash> Cas, std::function<void(const IoHash&)> KeepFunc)
+{
+ m_State->m_CasChunks.FilterChunks(Cas, [&](const IoHash& Hash) { KeepFunc(Hash); });
+}
+
+bool
+GcContext::IsDeletionMode() const
+{
+ return m_State->m_DeletionMode;
+}
+void
+GcContext::SetDeletionMode(bool NewState)
+{
+ m_State->m_DeletionMode = NewState;
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+GcContributor::GcContributor(CasGc& Gc) : m_Gc(Gc)
+{
+ m_Gc.AddGcContributor(this);
+}
+
+GcContributor::~GcContributor()
+{
+ m_Gc.RemoveGcContributor(this);
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+GcStorage::GcStorage(CasGc& Gc) : m_Gc(Gc)
+{
+ m_Gc.AddGcStorage(this);
+}
+
+GcStorage::~GcStorage()
+{
+ m_Gc.AddGcStorage(this);
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+CasGc::CasGc()
{
}
@@ -13,12 +101,103 @@ CasGc::~CasGc()
}
void
+CasGc::AddGcContributor(GcContributor* Contributor)
+{
+ RwLock::ExclusiveLockScope _(m_Lock);
+ m_GcContribs.push_back(Contributor);
+}
+
+void
+CasGc::RemoveGcContributor(GcContributor* Contributor)
+{
+ RwLock::ExclusiveLockScope _(m_Lock);
+ std::erase_if(m_GcContribs, [&](GcContributor* $) { return $ == 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()
{
+ RwLock::SharedLockScope _(m_Lock);
+
+ // First gather reference set
+
+ GcContext GcCtx;
+ GcCtx.SetDeletionMode(false);
+
+ for (GcContributor* Contributor : m_GcContribs)
+ {
+ Contributor->GatherReferences(GcCtx);
+ }
+
+ if (CidStore* CidStore = m_CidStore)
+ {
+ std::vector<IoHash> CasHashes;
+
+ int UnknownChunks = 0;
+
+ GcCtx.IterateCids([&](const IoHash& Hash) {
+ IoHash Cas = CidStore->RemapCid(Hash);
+
+ if (Cas == IoHash::Zero)
+ {
+ ++UnknownChunks;
+ }
+ else
+ {
+ CasHashes.push_back(Cas);
+ }
+ });
+
+ if (UnknownChunks)
+ {
+ ZEN_WARN("found {} unknown CIDs", UnknownChunks);
+ }
+
+ GcCtx.ContributeCas(CasHashes);
+ }
+
+ // Then trim storage
+
+ for (GcStorage* Storage : m_GcStorage)
+ {
+ Storage->CollectGarbage(GcCtx);
+ }
+}
+
+void
+CasGc::SetCidStore(CidStore* Cids)
+{
+ m_CidStore = Cids;
+}
+
+void
+CasGc::OnNewCidReferences(std::span<IoHash> Hashes)
+{
+ ZEN_UNUSED(Hashes);
+}
+
+void
+CasGc::OnCommittedCidReferences(std::span<IoHash> Hashes)
+{
+ ZEN_UNUSED(Hashes);
}
void
-CasGc::OnNewReferences(std::span<IoHash> Hashes)
+CasGc::OnDroppedCidReferences(std::span<IoHash> Hashes)
{
ZEN_UNUSED(Hashes);
}