aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcos Magueta <maguetamarcos@gmail.com>2026-08-02 23:37:13 -0300
committerEstevan Castilho <tevo@riajuu.net>2026-08-23 03:06:52 +0000
commitb762cb41da4d822416c3ab66940622882745fc0a (patch)
tree546d27d92f470d7f90ea7a76b6720039f3ed4291
parentcf050463faa996acaeb30fd81c4045b51573386d (diff)
downloadRNT-b762cb41da4d822416c3ab66940622882745fc0a.tar.gz
RNT-b762cb41da4d822416c3ab66940622882745fc0a.zip
photograph with runtime split for object manager
-rw-r--r--lib/backend/managers/Object.ml102
-rw-r--r--lib/kernel/Runtime.ml47
2 files changed, 123 insertions, 26 deletions
diff --git a/lib/backend/managers/Object.ml b/lib/backend/managers/Object.ml
index ae5f5c1..d54c89d 100644
--- a/lib/backend/managers/Object.ml
+++ b/lib/backend/managers/Object.ml
@@ -54,6 +54,17 @@ type registry = {reference_count: int; handle_count: int; pinned: bool; entry: r
type rnt_object_tree = {data: registry; subsequent: rnt_object_tree BatMap.String.t}
+module type RUNTIME_STRATEGY = sig
+ type 'a state
+
+ (* The exact snapshot observed on acquire *)
+ type 'a token
+
+ val create : 'a -> 'a state
+ val acquire : 'a state -> 'a * 'a token
+ val publish : 'a state -> 'a token -> 'a -> (unit, Concepts.Condition.condition) result
+end
+
module Error = struct
open Concepts.Condition
@@ -239,3 +250,94 @@ let unregister (path : Concepts.Path.t) (tree : rnt_object_tree) :
end
in
Result.map (fun tree -> adjust_references (-1) edges tree) (remove path tree)
+
+module type MANAGER = sig
+ type t
+
+ val create : branch_index_root:Concepts.Hash.hash -> registry:rnt_object_tree -> t
+ val branch_index_root : t -> Concepts.Hash.hash
+ val find : t -> Concepts.Path.t -> registry option
+
+ val update :
+ t -> Concepts.Path.t -> (registry -> registry) -> (unit, Concepts.Condition.condition) result
+
+ val register : t -> Concepts.Path.t -> rnt_object -> (unit, Concepts.Condition.condition) result
+ val unregister : t -> Concepts.Path.t -> (unit, Concepts.Condition.condition) result
+
+ val with_namespace :
+ t ->
+ Concepts.Path.t ->
+ string ->
+ (rnt_object_kind -> bool) ->
+ string ->
+ rnt_object ->
+ (unit, Concepts.Condition.condition) result
+
+ val construct_multigroup :
+ t -> Concepts.Path.t -> string -> multigroup -> (unit, Concepts.Condition.condition) result
+
+ val construct_relation :
+ t -> Concepts.Path.t -> string -> relation -> (unit, Concepts.Condition.condition) result
+end
+
+(* Keep the immutable tree operations above as the implementation core, while
+ this functor owns publication of the current photograph. Runtime bootstraps
+ the first photograph and exposes this opaque manager to its consumers. *)
+module Make (Strategy : RUNTIME_STRATEGY) : MANAGER = struct
+ type photograph = {branch_index_root: Concepts.Hash.hash; registry: rnt_object_tree}
+ type t = {state: photograph Strategy.state}
+
+ let create ~branch_index_root ~registry = {state= Strategy.create {branch_index_root; registry}}
+
+ let branch_index_root manager =
+ let photograph, _ = Strategy.acquire manager.state in
+ photograph.branch_index_root
+
+ let find manager path =
+ let photograph, _ = Strategy.acquire manager.state in
+ find path photograph.registry
+
+ let modify manager transformation =
+ let open Utilities.Result in
+ let photograph, token = Strategy.acquire manager.state in
+ let* next, result = transformation photograph in
+ let* () = Strategy.publish manager.state token next in
+ Ok result
+
+ let update manager path f =
+ modify manager (fun photograph ->
+ let registry = update path f photograph.registry in
+ Ok ({photograph with registry}, ()) )
+
+ let register manager path object_ =
+ modify manager (fun photograph ->
+ let open Utilities.Result in
+ let* registry = register path object_ photograph.registry in
+ Ok ({photograph with registry}, ()) )
+
+ let unregister manager path =
+ modify manager (fun photograph ->
+ let open Utilities.Result in
+ let* registry = unregister path photograph.registry in
+ Ok ({photograph with registry}, ()) )
+
+ let with_namespace manager parent namespace_label predicate name object_ =
+ modify manager (fun photograph ->
+ let open Utilities.Result in
+ let* registry =
+ with_namespace parent namespace_label predicate name object_ photograph.registry
+ in
+ Ok ({photograph with registry}, ()) )
+
+ let construct_multigroup manager parent name multigroup =
+ modify manager (fun photograph ->
+ let open Utilities.Result in
+ let* registry = construct_multigroup parent name multigroup photograph.registry in
+ Ok ({photograph with registry}, ()) )
+
+ let construct_relation manager parent name relation =
+ modify manager (fun photograph ->
+ let open Utilities.Result in
+ let* registry = construct_relation parent name relation photograph.registry in
+ Ok ({photograph with registry}, ()) )
+end
diff --git a/lib/kernel/Runtime.ml b/lib/kernel/Runtime.ml
index 6b4f5a4..aa69791 100644
--- a/lib/kernel/Runtime.ml
+++ b/lib/kernel/Runtime.ml
@@ -1,50 +1,45 @@
-module type REGISTRY_STRATEGY = sig
- type 'a state
- (* The exact snapshot observed on acquire *)
- type 'a token
-
- val create : 'a -> 'a state
- val acquire : 'a state -> 'a * 'a token
- val publish : 'a state -> 'a token -> 'a -> (unit, Concepts.Condition.condition) result
-end
-
module Error = struct
open Concepts.Condition
+
let registry_conflict () =
- let msg = "Failed to update the in-memory object registry." in
- condition "registry-object-update-conflict" msg empty
+ condition "registry-object-update-conflict" "Failed to update the in-memory object registry"
+ empty
end
-module CAS : REGISTRY_STRATEGY = struct
+module CAS : Backend.Managers.Object.RUNTIME_STRATEGY = struct
type 'a state = 'a Atomic.t
type 'a token = 'a
+
let create = Atomic.make
+
let acquire state =
let photograph = Atomic.get state in
- (* Just the same here because of CAS. On MVCC this would be a version number*)
photograph, photograph
+
let publish state token next =
- if Atomic.compare_and_set state token next then Ok ()
- else Error (Error.registry_conflict ())
+ if Atomic.compare_and_set state token next then Ok () else Error (Error.registry_conflict ())
end
(* module MVCC : REGISTRY_STRATEGY = struct end *)
(* module RCU : REGISTRY_STRATEGY = struct end *)
-module Make (Strategy : REGISTRY_STRATEGY) (Store: Abstract.Storage.STORAGE) = struct
- module Init = Initialization.Make(Store)
+module Make (Strategy : Backend.Managers.Object.RUNTIME_STRATEGY) (Store : Abstract.Storage.STORAGE) =
+struct
+ module Init = Initialization.Make (Store)
+ module Objects = Backend.Managers.Object.Make (Strategy)
- type photograph =
- { branch_index_root: Concepts.Hash.hash
- ; registry : Backend.Managers.Object.rnt_object_tree }
+ type t = {connection: Store.connection; objects: Objects.t}
- type t =
- { connection : Store.connection
- ; state : photograph Strategy.state }
-
let initialize configuration : (t, Concepts.Condition.condition) result =
let open Utilities.Result in
let* connection = Store.connect configuration in
let* branch_index_root = Init.initialize connection in
-
+ (* Registry reconstruction from the branch index is the loader boundary.
+ Until that loader exists, publish only the permanent /system namespace;
+ importantly, the discovered root remains part of the photograph. *)
+ let objects = Objects.create ~branch_index_root ~registry:Backend.Managers.Object.root in
+ Ok {connection; objects}
+
+ let connection runtime = runtime.connection
+ let objects runtime = runtime.objects
end