aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel/Merkle.ml
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kernel/Merkle.ml')
-rw-r--r--lib/kernel/Merkle.ml51
1 files changed, 47 insertions, 4 deletions
diff --git a/lib/kernel/Merkle.ml b/lib/kernel/Merkle.ml
index c2c2932..ababb03 100644
--- a/lib/kernel/Merkle.ml
+++ b/lib/kernel/Merkle.ml
@@ -23,9 +23,13 @@ module type TREE = functor (S : Abstract.Storage.STORAGE) (K : KEY) -> sig
val hash_of : node -> address
+ val persist : S.transaction -> node -> (address, Concepts.Condition.condition) result
+
val insert : S.transaction -> K.t -> address -> node -> (node, Concepts.Condition.condition) result
val remove : S.transaction -> K.t -> node -> (node, Concepts.Condition.condition) result
val lookup : S.transaction -> K.t -> node -> (address option, Concepts.Condition.condition) result
+
+ val fold_left : S.transaction -> ('c -> K.t -> address -> 'c) -> 'c -> node -> ('c, Concepts.Condition.condition) result
end
module Make : TREE = functor (S : Abstract.Storage.STORAGE) (K : KEY) -> struct
@@ -76,7 +80,7 @@ module Make : TREE = functor (S : Abstract.Storage.STORAGE) (K : KEY) -> struct
let decode_list f data = data
|> fmap as_list
|> Result.map (List.map f)
- |> fmap sequence
+ |> fmap Utilities.List.sequence
|> Result.map BatFingerTree.of_list in
function
| Tagged ('!', (Dict _ as data)) ->
@@ -116,7 +120,7 @@ module Make : TREE = functor (S : Abstract.Storage.STORAGE) (K : KEY) -> struct
be used for intermediates and the like. *)
let hash_of node = to_blob node |> Concepts.Hash.hash_of_blob
- let find tx node =
+ let find tx addr =
let open Utilities.Result in
let* data = S.get tx (S.Hash node) in
match data with
@@ -125,9 +129,9 @@ module Make : TREE = functor (S : Abstract.Storage.STORAGE) (K : KEY) -> struct
let* node = from_blob data in
Ok (Some node)
- let find' tx node =
+ let find' tx addr =
let open Utilities.Result in
- let* child = find tx node in
+ let* child = find tx addr in
match child with
| Some child -> Ok child
| None -> failwith "A child node was not found on the underlying storage. Either your database is corrupted, or this is a bug on RNT!"
@@ -283,6 +287,22 @@ module Make : TREE = functor (S : Abstract.Storage.STORAGE) (K : KEY) -> struct
Ok new_root
let remove tx key node = failwith "TODO" [@@warning "-27"]
+
+ let rec fold_left tx f acc =
+ let open Utilities.Result in
+ function
+ | Leaf { keys; values } ->
+ Utilities.FingerTree.zip keys values
+ |> BatFingerTree.fold_left (fun acc (k, v) -> f acc k v) acc
+ |> Result.ok
+ | Trunk { children; _ } ->
+ BatFingerTree.fold_left
+ (fun acc addr ->
+ let* acc = acc in
+ let* node = find' tx addr in
+ fold_left tx f acc node)
+ (Ok acc) children
+
end
module type INTERFACE = functor (S : Abstract.Storage.STORAGE) (K : KEY) (V : VALUE) -> sig
@@ -298,6 +318,10 @@ module type INTERFACE = functor (S : Abstract.Storage.STORAGE) (K : KEY) (V : VA
val insert : S.transaction -> K.t -> V.t -> node -> (node, Concepts.Condition.condition) result
val remove : S.transaction -> K.t -> node -> (node, Concepts.Condition.condition) result
val lookup : S.transaction -> K.t -> node -> (V.t option, Concepts.Condition.condition) result
+
+ val fold_left : S.transaction -> ('c -> K.t -> V.t -> 'c) -> 'c -> node -> ('c, Concepts.Condition.condition) result
+
+ val iter : S.transaction -> (K.t -> V.t -> 'a) -> node -> (unit, Concepts.Condition.condition) result
end
module Interface : INTERFACE = functor (S : Abstract.Storage.STORAGE) (K : KEY) (V : VALUE) -> struct
@@ -322,6 +346,12 @@ module Interface : INTERFACE = functor (S : Abstract.Storage.STORAGE) (K : KEY)
let* v = V.decode data in
Ok (Some v)
+ let retrieve' tx addr =
+ let* v = retrieve tx addr in
+ match v with
+ | Some v -> Ok v
+ | None -> failwith "A value was not found on the underlying storage. Either your database is corrupted, or this is a bug on RNT!"
+
let find = T.find
let empty = T.empty
let hash_of = T.hash_of
@@ -338,6 +368,19 @@ module Interface : INTERFACE = functor (S : Abstract.Storage.STORAGE) (K : KEY)
| None -> Ok None
| Some addr -> retrieve tx addr
+ let fold_left tx f acc node =
+ T.fold_left tx
+ (fun acc k addr ->
+ let* acc = acc in
+ let* v = retrieve' tx addr in
+ Ok (f acc k v))
+ (Ok acc) node
+ |> Result.join
+
+ let iter tx f node =
+ fold_left tx
+ (fun _ k v -> f k v |> ignore)
+ () node
end
module StringKey : KEY with type t = string = struct