aboutsummaryrefslogtreecommitdiffstats
path: root/include/LifecycleManager.h
diff options
context:
space:
mode:
authorMarcos Magueta <maguetamarcos@gmail.com>2026-05-18 12:50:25 -0300
committerGitHub <noreply@github.com>2026-05-18 12:50:25 -0300
commitaf8759a9c1d965a3220024d1857aea219d62d898 (patch)
tree9cf14af855cac3674f508ec001bd04e262a524ae /include/LifecycleManager.h
parent0fc76b99abbff1d3cef8e2f9fcd56f3ae4f23a7a (diff)
downloadRNT-af8759a9c1d965a3220024d1857aea219d62d898.tar.gz
RNT-af8759a9c1d965a3220024d1857aea219d62d898.zip
Branching and object registry rework (#11)
Diffstat (limited to 'include/LifecycleManager.h')
-rw-r--r--include/LifecycleManager.h75
1 files changed, 69 insertions, 6 deletions
diff --git a/include/LifecycleManager.h b/include/LifecycleManager.h
index 8126820..5508bc6 100644
--- a/include/LifecycleManager.h
+++ b/include/LifecycleManager.h
@@ -1,6 +1,7 @@
#pragma once
#include "Api.h"
+#include "IStorageBackend.h"
#include "ObjectManager.h"
/**
@@ -15,9 +16,9 @@ namespace nt
*
* Object lifetime is governed by two independent counters in registry_head:
* `handle_count` (sessions holding an open handle) and `reference_count`
- * (structural dependencies such as cursors pinned to a snapshot or views
- * referencing base relations). An object is eligible for GC only when both
- * reach zero.
+ * (structural dependencies such as cursors pinned to a snapshot or
+ * ephemeral relations referencing their base relations). An object is
+ * eligible for GC only when both reach zero.
*
* Monitor / Unmonitor manage `handle_count`. Pin / Unpin manage
* `reference_count`. See docs/reactos-ob-comparison.md §1.
@@ -26,6 +27,18 @@ namespace nt
{
public:
/**
+ * @brief Constructs a LifecycleManager bound to a registry and store.
+ *
+ * Needs the registry to perform GC: Unmonitor and Unpin call
+ * ObjectManager::Unregister once both counters reach zero. Type-specific
+ * cleanup (e.g. cascading a Multigroup's pin to its child Relations,
+ * or a BranchTree's pin to its child Multigroups) runs inside the
+ * lifecycle manager before the entry is spliced out. The storage
+ * backend is needed by CascadeBranchTree to page the merkle nodes.
+ */
+ LifecycleManager(ObjectManager& objects, IStorageBackend& storage);
+
+ /**
* @brief Starts monitoring an object's lifecycle.
*
* Increments `handle_count` on the object's registry_head. Should be
@@ -53,9 +66,9 @@ namespace nt
* @brief Increments the structural dependency count on an object.
*
* Call when one object takes a dependency on another — for example when
- * a cursor pins an immutable snapshot version, or when a view is
- * registered against its base relations. Prevents GC of the target object
- * while the dependency is live.
+ * a cursor pins an immutable snapshot version, or when an ephemeral
+ * relation is registered against its base relations. Prevents GC of the
+ * target object while the dependency is live.
*
* @todo Implement. See docs/reactos-ob-comparison.md §1.
*
@@ -76,6 +89,15 @@ namespace nt
void Unpin(ObjectManager::registry* object);
/**
+ * @brief Returns true when the object is GC-eligible right now.
+ *
+ * Eligibility is the joint condition handle_count == 0 &&
+ * reference_count == 0. Decrement callers (Unmonitor / Unpin) consult
+ * this and, when true, run type-specific cleanup before unregistering.
+ */
+ bool IsEligibleForGC(ObjectManager::registry* object) const;
+
+ /**
* @brief Serializes contention for changes to mutable reference states.
*
* Immutable objects — relation snapshots, multigroup snapshots,
@@ -97,5 +119,46 @@ namespace nt
* @return True when the operation may proceed.
*/
const bool Contention(ObjectManager::registry* object);
+
+ private:
+ /**
+ * @brief Joint-counters check + type-specific cascade + Unregister.
+ *
+ * Called by Unmonitor and Unpin after their decrement. No-op when the
+ * object is still referenced. When eligible:
+ * - MULTIGROUP entries first unpin every Relation registered as a
+ * direct child of their /system/snapshots/H subtree.
+ * - BRANCH_TREE entries first unpin every Multigroup their
+ * content-addressed tree references.
+ * - The entry is then removed from the registry; its IObject and
+ * registry_head are freed.
+ *
+ * Inline GC for now; the reaper-queue deferred-deletion pattern from
+ * docs/reactos-ob-comparison.md §7 is a later optimisation.
+ */
+ void TryCollect(ObjectManager::registry* object);
+
+ /**
+ * @brief Releases pins held by a MULTIGROUP entry on its child Relations.
+ *
+ * Iterates the registry once, collects every /system/snapshots/<H>/<n>
+ * direct child, and calls Unpin on each. Triggered exclusively from
+ * TryCollect at the moment the parent snapshot becomes eligible for GC.
+ */
+ void CascadeMultigroup(ObjectManager::registry* multigroup);
+
+ /**
+ * @brief Releases pins held by a BRANCH_TREE entry on its child mgs.
+ *
+ * Pages the Merkle<std::string> tree at the BranchTree's merkle_root,
+ * resolves each (mg_name, mg_hash) entry to its
+ * /system/snapshots/<mg_hash> Multigroup, and calls Unpin on it.
+ * Triggered exclusively from TryCollect at the moment the BranchTree
+ * itself becomes eligible for GC.
+ */
+ void CascadeBranchTree(ObjectManager::registry* branch_tree);
+
+ ObjectManager& objects_;
+ IStorageBackend& storage_;
};
}