forked from
gazagnaire.org/irmin
Persistent store with Git semantics: lazy reads, delayed writes, content-addressing
1(** Storage backends for Irmin.
2
3 Backends are records of functions, NOT functors. This makes them composable
4 and easy to create without functor application. *)
5
6(** {1 Backend Interface} *)
7
8type 'hash t = {
9 read : 'hash -> string option;
10 (** [read hash] retrieves the object with the given hash. *)
11 write : 'hash -> string -> unit;
12 (** [write hash data] stores [data] at [hash]. Caller computes the hash.
13 *)
14 exists : 'hash -> bool; (** [exists hash] checks if an object exists. *)
15 get_ref : string -> 'hash option;
16 (** [get_ref name] reads a reference (branch/tag). *)
17 set_ref : string -> 'hash -> unit;
18 (** [set_ref name hash] sets a reference. *)
19 test_and_set_ref : string -> test:'hash option -> set:'hash option -> bool;
20 (** [test_and_set_ref name ~test ~set] atomically updates a reference if
21 its current value matches [test]. *)
22 list_refs : unit -> string list;
23 (** [list_refs ()] returns all reference names. *)
24 write_batch : ('hash * string) list -> unit;
25 (** [write_batch [(h1, d1); ...]] writes multiple objects efficiently. *)
26 flush : unit -> unit; (** [flush ()] ensures all writes are persisted. *)
27 close : unit -> unit; (** [close ()] releases resources. *)
28}
29
30(** {1 Memory Backend} *)
31
32module Memory : sig
33 val create_with_hash : ('h -> string) -> ('h -> 'h -> bool) -> 'h t
34 (** [create_with_hash to_hex equal] creates an in-memory backend. Caller
35 computes hashes; backend just stores (hash, data) pairs. *)
36
37 val create_sha1 : unit -> Hash.sha1 t
38 (** Create an in-memory SHA-1 backend. *)
39
40 val create_sha256 : unit -> Hash.sha256 t
41 (** Create an in-memory SHA-256 backend. *)
42end
43
44(** {1 Backend Combinators} *)
45
46val cached : 'h t -> 'h t
47(** [cached backend] wraps a backend with an LRU cache. Reads are served from
48 cache when possible. *)
49
50val readonly : 'h t -> 'h t
51(** [readonly backend] makes a backend read-only. Write operations raise
52 [Invalid_argument]. *)
53
54val layered : upper:'h t -> lower:'h t -> 'h t
55(** [layered ~upper ~lower] creates a layered backend. Reads check upper first,
56 then lower. Writes go to upper only. Used for garbage collection
57 (upper=live, lower=frozen). *)
58
59(** {1 Disk Backend} *)
60
61module Disk : sig
62 val create_with_hash :
63 sw:Eio.Switch.t ->
64 Eio.Fs.dir_ty Eio.Path.t ->
65 ('h -> string) ->
66 (string -> ('h, [ `Msg of string ]) result) ->
67 ('h -> 'h -> bool) ->
68 'h t
69 (** [create_with_hash ~sw root to_hex of_hex equal] creates a disk-based
70 backend at [root]. Uses append-only storage for objects with an index file
71 for lookups.
72
73 Storage layout:
74 - objects.data: append-only file containing all objects
75 - objects.idx: index mapping hex hash to (offset, length)
76 - refs/: directory with one file per ref *)
77
78 val create_sha1 : sw:Eio.Switch.t -> Eio.Fs.dir_ty Eio.Path.t -> Hash.sha1 t
79 (** Create a disk-based SHA-1 backend. *)
80
81 val create_sha256 :
82 sw:Eio.Switch.t -> Eio.Fs.dir_ty Eio.Path.t -> Hash.sha256 t
83 (** Create a disk-based SHA-256 backend. *)
84end
85
86(** {1 Statistics} *)
87
88type stats = { reads : int; writes : int; cache_hits : int; cache_misses : int }
89
90val stats : _ t -> stats option
91(** [stats backend] returns statistics if the backend tracks them. *)