diff options
Diffstat (limited to 'lib/kernel/Merkle.ml')
| -rw-r--r-- | lib/kernel/Merkle.ml | 51 |
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 |
