aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorEstevan Castilho <tevo@riajuu.net>2026-08-20 00:18:32 +0000
committerEstevan Castilho <tevo@riajuu.net>2026-08-23 03:06:57 +0000
commitebea139a01d1ca3f53df9671ff4ebf7990ac26d4 (patch)
treea897b2bacad96ce763ec9b22cd0f68fd5710a5a7 /lib
parent465f3378daea5a6f0d44f3729c3551a9cda78ed9 (diff)
downloadRNT-ebea139a01d1ca3f53df9671ff4ebf7990ac26d4.tar.gz
RNT-ebea139a01d1ca3f53df9671ff4ebf7990ac26d4.zip
Make `update` a bit more like compare-and-swap
Diffstat (limited to 'lib')
-rw-r--r--lib/kernel/BranchManager.ml36
-rw-r--r--lib/kernel/BranchManager.mli6
2 files changed, 23 insertions, 19 deletions
diff --git a/lib/kernel/BranchManager.ml b/lib/kernel/BranchManager.ml
index 71a25b3..80e32a4 100644
--- a/lib/kernel/BranchManager.ml
+++ b/lib/kernel/BranchManager.ml
@@ -1,21 +1,26 @@
-module BranchValue = Merkle.StringKey (* FIXME *)
-
type branch = string
module Error = struct
open Concepts.Condition
- let invalid_root head = condition "invalid-root" "The root hash for the database state is missing from the backend. Either your storage is corrupted, or this is a bug in RNT!"
- ("hash" |=| (Concepts.Value.String (Concepts.Hash.to_hum_string head)))
+ let invalid_root head =
+ condition "invalid-root" "The root hash for the database state is missing from the backend. Either your storage is corrupted, or this is a bug in RNT!"
+ ("hash" |=| (Concepts.Value.String (Concepts.Hash.to_hum_string head)))
+
+ let comparison_failed branch_name reference head =
+ condition "comparison-failed" "The HEAD of the branch did not match what was expected"
+ ("branch" |=| Concepts.Value.String branch_name &
+ "reference" |=| Concepts.Value.String (Concepts.Hash.to_hum_string reference) &
+ "head" |=| Concepts.Value.String (Concepts.Hash.to_hum_string head))
end
module Make (S : Abstract.Storage.STORAGE) = struct
- module I = Merkle.Interface (S) (Merkle.StringKey) (BranchValue)
+ module M = Merkle.Make (S) (Merkle.StringKey)
module SI = Storage.Make (S)
type manager = { storage: S.connection;
label : string;
- head: I.node Atomic.t }
+ head: M.node Atomic.t }
let root_for tx label =
let open Utilities.Result in
@@ -23,8 +28,6 @@ module Make (S : Abstract.Storage.STORAGE) = struct
let label = Option.map Concepts.Hash.hash_of_blob label in
Ok label
- let persist_root tx label new_branch = failwith "TODO"
-
let initialize storage label =
let open Utilities.Result in
SI.with_transaction storage (fun tx ->
@@ -32,22 +35,25 @@ module Make (S : Abstract.Storage.STORAGE) = struct
match addr with
| None -> failwith "TODO"
| Some addr ->
- let* head = I.find tx addr in
+ let* head = M.find tx addr in
let* head = Option.to_result ~none:(Error.invalid_root addr) head in
Ok { storage; label; head = Atomic.make head })
let fetch { storage; head; _ } branch_name =
SI.with_transaction storage (fun tx ->
let head = Atomic.get head in
- I.lookup tx branch_name head)
+ M.lookup tx branch_name head)
- let update ({ storage; head; label } as manager) branch_name f =
+ let update ({ storage; head; label } as manager) branch_name reference new_branch =
let open Utilities.Result in
let* _ = SI.with_transaction storage (fun tx ->
Utilities.Atomic.mswap head (fun head ->
- let* branch = I.lookup tx branch_name head in
- let new_branch = f branch in
- let* () = persist_root tx label new_branch in
- new_branch)) in
+ let* branch = M.lookup tx branch_name head in
+ if branch = reference then
+ let* new_head = M.insert tx label new_branch head in
+ new_head
+ else
+ Error.comparison_failed branch_name reference branch)) in
Ok ()
+
end
diff --git a/lib/kernel/BranchManager.mli b/lib/kernel/BranchManager.mli
index 063f8a7..052f9a1 100644
--- a/lib/kernel/BranchManager.mli
+++ b/lib/kernel/BranchManager.mli
@@ -1,11 +1,9 @@
-type branch = string (* FIXME *)
-
module Make (S : Abstract.Storage.STORAGE) : sig
type manager
val initialize : S.connection -> string -> (manager, Concepts.Condition.condition) result
- val fetch : manager -> string -> (branch option, Concepts.Condition.condition) result
- val update : manager -> string -> (branch -> branch) -> (manager, Concepts.Condition.condition) result
+ val fetch : manager -> string -> (Concepts.Hash.hash option, Concepts.Condition.condition) result
+ val update : manager -> string -> Concepts.Hash.hash -> Concepts.Hash.hash -> (unit, Concepts.Condition.condition) result
(* TODO: fork, join *)
end