diff options
| author | Marcos Magueta <maguetamarcos@gmail.com> | 2026-10-07 18:25:43 -0300 |
|---|---|---|
| committer | Marcos Magueta <maguetamarcos@gmail.com> | 2026-10-07 18:25:43 -0300 |
| commit | 932e657e38665afa1da1aab549977841abbd9dcf (patch) | |
| tree | b2c0b3d30b7aaab7347300b3932a9f03e4f64f9a /lib/kernel/Journal.ml | |
| parent | cfc641a9bb97c94e5993f895a8bcdf24214adc83 (diff) | |
| download | RNT-932e657e38665afa1da1aab549977841abbd9dcf.tar.gz RNT-932e657e38665afa1da1aab549977841abbd9dcf.zip | |
drop journal in favor of local branch history
Diffstat (limited to 'lib/kernel/Journal.ml')
| -rw-r--r-- | lib/kernel/Journal.ml | 198 |
1 files changed, 0 insertions, 198 deletions
diff --git a/lib/kernel/Journal.ml b/lib/kernel/Journal.ml deleted file mode 100644 index 13782a5..0000000 --- a/lib/kernel/Journal.ml +++ /dev/null @@ -1,198 +0,0 @@ -module J = Protocols.Journal -module Bindings = BatMap.String - -module Error = struct - open Concepts.Condition - - let empty_commit () = condition "empty-commit" "A commit has to change at least one name" empty - - let repeated_name name = - condition "repeated-name" "A commit names the same binding twice" - ("name" |=| Concepts.Value.String name) -end - -(* A snapshot is named by its bindings, so two snapshots binding the - same objects are the same snapshot. *) -let identity bindings = - Bindings.fold - (fun name handle acc -> - name :: Concepts.Hash.to_raw_string (Protocols.Handle.hash handle) :: acc ) - bindings [] - |> String.concat "\000" - |> Bytes.of_string - |> Concepts.Hash.hash_of_bytes - -class snapshot bindings = - object (self) - inherit Lifecycle.null - method to_string = "snapshot" - method hash = identity bindings - val mutable handle : Protocols.Handle.t option = None - method protocols : Protocols.Handle.protocol list = [Protocols.Directory.make self] - method list = Ok (Bindings.keys bindings |> BatFingerTree.of_enum) - - method find name = - match Bindings.find_opt name bindings with - | None -> Ok None - | Some bound -> ( - match Protocols.Derived.from bound, handle with - | Some derived, Some me -> Protocols.Derived.within derived me |> Result.map Option.some - | _ -> Ok (Protocols.Handle.copy bound) ) - - method attach me = handle <- Some me - end - -let snapshot_of bindings = - let o = new snapshot bindings in - let handle = Protocols.Handle.make o in - o#attach handle; handle - -let snapshot bindings = snapshot_of (Bindings.of_list bindings) - -type state = {commit: J.commit; bindings: Protocols.Handle.t Bindings.t} - -class journal bindings = - object (self) - inherit Lifecycle.null - inherit Identity.of_id - method to_string = "journal" - val lock = Mutex.create () - - (* the latest first *) - val mutable states = - [ { commit= - { J.number= 0; - snapshot= snapshot_of bindings; - changed= Bindings.keys bindings |> BatList.of_enum }; - bindings } ] - - val mutable guards : (string * J.guard) list = [] - val mutable observers : (string * J.observer) list = [] - - method protocols : Protocols.Handle.protocol list = - Protocols.[Directory.make self; Registry.make self; J.make self] - - method head = (List.hd states).commit - method history = List.rev_map (fun {commit; _} -> commit) states - - method guard name g = - Mutex.protect lock (fun () -> - guards <- - List.remove_assoc name guards @ Option.fold ~none:[] ~some:(fun g -> [name, g]) g ) - - method observe name f = - Mutex.protect lock (fun () -> - observers <- - List.remove_assoc name observers @ Option.fold ~none:[] ~some:(fun f -> [name, f]) f ) - - method list = Ok (Bindings.keys (List.hd states).bindings |> BatFingerTree.of_enum) - - method find name = - Ok - ( Bindings.find_opt name (List.hd states).bindings - |> Utilities.Option.fmap Protocols.Handle.copy ) - - method update name expected replacement = - self#commit [{J.name; expected; replacement}] |> Result.map Option.is_some - - (* Guards run in the order they were installed, and observers after - the commit has landed, both while holding the journal, so they - see commits one at a time and in order. *) - method commit (changes : J.change list) = - let open Utilities.Result in - let names = List.map (fun (c : J.change) -> c.name) changes in - let repeated = - List.find_opt (fun n -> List.length (List.filter (String.equal n) names) > 1) names - in - match changes, repeated with - | [], _ -> Error (Error.empty_commit ()) - | _, Some name -> Error (Error.repeated_name name) - | _ -> - Mutex.protect lock (fun () -> - let current = List.hd states in - let expected (c : J.change) = - Bindings.find_opt c.name current.bindings = c.expected - in - if not (List.for_all expected changes) then Ok None - else - let bindings = - List.fold_left - (fun bindings (c : J.change) -> - match c.replacement with - | Some h -> Bindings.add c.name h bindings - | None -> Bindings.remove c.name bindings ) - current.bindings changes - in - let commit = - { J.number= current.commit.number + 1; - snapshot= snapshot_of bindings; - changed= names } - in - let proposal = {J.previous= current.commit; proposed= commit} in - let* () = - List.fold_left - (fun acc (_, g) -> - let* () = acc in - g proposal ) - (Ok ()) guards - in - states <- {commit; bindings} :: states; - List.iter (fun (_, f) -> f commit) observers; - Ok (Some commit) ) - end - -let make ?(bindings = []) () = Protocols.Handle.make (new journal (Bindings.of_list bindings)) - -let adopt directory = - let open Utilities.Result in - let* listing = Protocols.Handle.require Protocols.Directory.from directory in - let* names = Protocols.Directory.list listing in - let* bindings = - BatFingerTree.to_list names - |> List.map (fun name -> - let* found = Protocols.Directory.find listing name in - Ok (Option.map (fun h -> name, h) found) ) - |> Utilities.List.sequence - in - Ok (make ~bindings:(List.filter_map Fun.id bindings) ()) - -(* What a name is bound to is read as a copy, which has to stay valid - until the swap has compared against it. *) -let rebind directory bindings = - let open Utilities.Result in - let* listing = Protocols.Handle.require Protocols.Directory.from directory in - let holding names f = - let* found = - List.map (fun name -> Protocols.Directory.find listing name) names |> Utilities.List.sequence - in - Fun.protect - ~finally:(fun () -> List.iter (Option.iter Protocols.Handle.release) found) - (fun () -> f found) - in - let rec together journal = - let* landed = - holding (List.map fst bindings) (fun found -> - List.map2 - (fun (name, replacement) expected -> {J.name; expected; replacement}) - bindings found - |> J.commit journal ) - in - match landed with Some _ -> Ok () | None -> together journal - in - let rec one registry name replacement = - let* swapped = - holding [name] (fun found -> - Protocols.Registry.update registry name (List.hd found) replacement ) - in - if swapped then Ok () else one registry name replacement - in - match J.from directory, bindings with - | _, [] -> Ok () - | Some journal, _ -> together journal - | None, _ -> - let* registry = Protocols.Handle.require Protocols.Registry.from directory in - List.fold_left - (fun acc (name, replacement) -> - let* () = acc in - one registry name replacement ) - (Ok ()) bindings |
