forked from
gazagnaire.org/irmin
Persistent store with Git semantics: lazy reads, delayed writes, content-addressing
1(** Lazy trees with delayed writes.
2
3 Trees are like Git's staging area: immutable, temporary, non-persistent
4 areas held in memory. Reads are done lazily and writes are accumulated until
5 commit - if you modify a key twice, only the last change is written. *)
6
7(** {1 Tree Functor} *)
8
9module Make (F : Codec.S) : sig
10 type t
11 (** Immutable in-memory tree with lazy reads and delayed writes. *)
12
13 type hash = F.hash
14
15 (** {2 Path Type} *)
16
17 type path = string list
18 (** A path is a list of path segments. *)
19
20 (** {2 Concrete Trees} *)
21
22 type concrete = [ `Contents of string | `Tree of (string * concrete) list ]
23 (** Fully materialized tree for import/export. *)
24
25 (** {2 Construction} *)
26
27 val empty : unit -> t
28 (** [empty ()] creates an empty tree. *)
29
30 val of_hash : backend:hash Backend.t -> hash -> t
31 (** [of_hash ~backend h] creates a tree backed by the store. Nothing is loaded
32 until accessed (lazy reads). *)
33
34 val of_concrete : concrete -> t
35 (** [of_concrete c] creates a tree from a fully materialized tree. *)
36
37 val shallow : hash -> t
38 (** [shallow h] creates a tree with only a hash reference. Accessing contents
39 raises an error. *)
40
41 val pruned : hash -> t
42 (** [pruned h] creates a pruned tree that raises on dereference. Used for GC
43 and export operations. *)
44
45 (** {2 Reads (Lazy)} *)
46
47 val find : t -> path -> string option
48 (** [find t path] looks up contents at [path]. Loads nodes lazily as needed.
49 *)
50
51 val find_tree : t -> path -> t option
52 (** [find_tree t path] looks up a subtree at [path]. *)
53
54 val list : t -> path -> (string * [ `Node | `Contents ]) list
55 (** [list t path] lists entries at [path]. *)
56
57 val mem : t -> path -> bool
58 (** [mem t path] checks if [path] exists. *)
59
60 val mem_tree : t -> path -> bool
61 (** [mem_tree t path] checks if a subtree exists at [path]. *)
62
63 (** {2 Writes (Delayed)} *)
64
65 val add : t -> path -> string -> t
66 (** [add t path contents] adds contents at [path]. The write is accumulated,
67 not performed immediately. *)
68
69 val add_tree : t -> path -> t -> t
70 (** [add_tree t path subtree] adds a subtree at [path]. *)
71
72 val remove : t -> path -> t
73 (** [remove t path] removes the entry at [path]. *)
74
75 (** {2 Materialization} *)
76
77 val to_concrete : t -> concrete
78 (** [to_concrete t] fully materializes the tree. Forces all lazy nodes to be
79 loaded. *)
80
81 val hash : t -> backend:hash Backend.t -> hash
82 (** [hash t ~backend] computes the tree hash. Writes all accumulated changes
83 to the backend. *)
84
85 (** {2 Force Control} *)
86
87 type 'a force = [ `True | `False of hash -> 'a | `Shallow of hash -> 'a ]
88 (** Control how lazy nodes are handled during traversal:
89 - [`True]: force loading of all nodes
90 - [`False f]: call [f] on unloaded hashes instead
91 - [`Shallow f]: like [`False] but for shallow trees *)
92
93 val fold :
94 ?force:'a force ->
95 t ->
96 'a ->
97 (path -> [ `Contents of string | `Tree ] -> 'a -> 'a) ->
98 'a
99 (** [fold ~force t init f] traverses the tree. The [force] parameter controls
100 lazy loading behavior. *)
101
102 (** {2 Cache Management} *)
103
104 val clear : ?depth:int -> t -> unit
105 (** [clear ?depth t] purges cached data. If [depth] is given, only clears
106 nodes at that depth or deeper. *)
107
108 (** {2 Comparison} *)
109
110 val equal : t -> t -> bool
111 (** [equal t1 t2] compares trees structurally. *)
112end
113
114(** {1 Pre-instantiated Trees} *)
115
116module Git : module type of Make (Codec.Git)
117(** Git-format trees with SHA-1 hashes. *)
118
119module Mst : module type of Make (Codec.Mst)
120(** MST-format trees with SHA-256 hashes. *)