aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel/Multigroup.ml
diff options
context:
space:
mode:
authorEstevan Castilho <tevo@riajuu.net>2026-09-11 04:06:52 +0000
committerGitHub <noreply@github.com>2026-09-11 01:06:52 -0300
commitb79224410f469a1cd4ff3be4f8e62d71398109fc (patch)
treee025feebbdf9703ce790b4a97cb9997242c9bb4b /lib/kernel/Multigroup.ml
parentefe8032f7e224c29fc67a4f8cfd52db908442eec (diff)
downloadRNT-b79224410f469a1cd4ff3be4f8e62d71398109fc.tar.gz
RNT-b79224410f469a1cd4ff3be4f8e62d71398109fc.zip
Multigroup objects
Diffstat (limited to '')
-rw-r--r--lib/kernel/Multigroup.ml65
-rw-r--r--lib/kernel/Multigroup.mli9
2 files changed, 74 insertions, 0 deletions
diff --git a/lib/kernel/Multigroup.ml b/lib/kernel/Multigroup.ml
new file mode 100644
index 0000000..685c8c7
--- /dev/null
+++ b/lib/kernel/Multigroup.ml
@@ -0,0 +1,65 @@
+module Make (S : Abstract.Storage.STORAGE) = struct
+ module SI = Storage.Make (S)
+
+ module R = SubstantialRelation.Make (S)
+ module RelationM = Merkle.Interface (S) (Merkle.StringKey) (R)
+ module RMDirectory = Prototype.Directory.OfTree (S) (Merkle.StringKey) (R)
+
+ type t = { relations : RelationM.address }
+
+ module Error = struct
+ open Concepts.Condition
+
+ let malformed_multigroup () = condition "malformed-multigroup" "The on-disk representation of a multigroup did not conform to what was expected. Is your database corrupted?"
+ empty
+
+ let incomplete_multigroup addr = condition "incomplete-multigroup" "A stored multigroup is missing part of its expected structure. Is your storage corrupted?"
+ ("address" |=| Concepts.Value.String (Concepts.Hash.to_hum_string addr))
+ end
+
+ module rec Representation : Concepts.Encoding.Record.S with type t = t = Concepts.Encoding.Record.Make (Body)
+ and Body : Concepts.Encoding.Record.BODY = struct
+ type nonrec t = t
+
+ let tag = '*'
+ let malformed = Error.malformed_multigroup
+
+ let fields { relations } =
+ let open Concepts.Encoding in
+ ["relations", Value.bencode_of_hash relations]
+
+ let of_fields fields =
+ let open Utilities.Result in
+ let open Concepts.Encoding in
+ let* relations = Bencode.field "relations" fields |> fmap Value.hash_of_bencode in
+ Ok { relations }
+ end
+
+ let encode = Representation.to_blob
+ let decode = Representation.of_blob
+
+ class multigroup conn value node = object
+ inherit Lifecycle.null
+
+ val multigroup = value
+ val storage = conn
+ val node = node (* FIXME: see the comment on Branch.ml *)
+
+ method protocols : Protocols.Handle.protocol list =
+ [ Prototype.Directory.of_properties
+ [ "relation", Prototype.mixture
+ [ RMDirectory.make
+ ~storage ~node
+ ~constructor:(R.wrap storage) ] ] ]
+
+ method hash =
+ Representation.to_blob multigroup
+ |> Concepts.Hash.hash_of_blob
+ end
+
+ let wrap conn value =
+ let open Utilities.Result in
+ let* node = SI.with_transaction conn (fun tx -> RelationM.find tx value.relations)
+ |> fmap (Option.to_result ~none:(Error.incomplete_multigroup value.relations)) in
+ new multigroup conn value node |> Protocols.Handle.make |> Result.ok
+end
diff --git a/lib/kernel/Multigroup.mli b/lib/kernel/Multigroup.mli
new file mode 100644
index 0000000..88aee30
--- /dev/null
+++ b/lib/kernel/Multigroup.mli
@@ -0,0 +1,9 @@
+module Make (S : Abstract.Storage.STORAGE) : sig
+ type t
+
+ val encode : t -> Concepts.Blob.t
+ val decode : Concepts.Blob.t -> (t, Concepts.Condition.condition) result
+
+ val wrap : S.connection -> t -> (Protocols.Handle.t, Concepts.Condition.condition) result
+
+end