package b0

  1. Overview
  2. Docs

File caches.

A file cache maps a key to a metadata hunk and an ordered list of file contents (filenames are irrelevant).

Cache bindings are used to recreate the effect of build operations without having to rerun them. The key identifies the operation (usually via a hash), the ordered files are those written by the operation and the metadata has additional output information (e.g. exit codes, standard outputs, etc.).

For some scenarios it may still be useful to store relative not only file contents but also relative file paths associated to them. Thus for certain keys these are stored along side the file contents.

Note. In general, whenever a cache operation modifies the file system and errors with Error _ the resulting file system state is undefined.

File caches

type key = string

The type for keys. A key maps to a metadata hunk and an ordered list of file contents. The module treats keys as sequence of bytes however since they are used as file names they should satisfy the B00_std.Fpath.is_seg predicate; this is not checked by the module.

type t

The type for file caches.

val create : B00_std.Fpath.t -> (t, string) result

create dir is a file cache using directory dir for data storage. The full path to dir is created by the call if dir doesn't exist.

val dir : t -> B00_std.Fpath.t

dir c is c's storage directory.

val keys : t -> (key list, string) result

keys c are the keys of cache c.

val key_stats : t -> key -> (int * int * float, string) result

key_stats c key is statistical information about key key. Namely the number of files (including the metadata and manifest), the key size in bytes and the access time of the key – this is the latest access time of one of its consituents the relevance of which depends on your file system.

val mem : t -> key -> bool

mem c k is true iff k is bound in c.

val add : t -> key -> string -> B00_std.Fpath.t list -> (bool, string) result

add c k m fs, binds the metadata m and the contents of the ordered list of files fs to k in c. The function returns:

  • Ok true if the operation succeeds.
  • Ok false if a file of fs could not be accessed. In this case k is guaranteed to be unbound in c.
  • Error _ if an unexpected error occurs. In that case the resulting state of the cache for key k is undefined.
val manifest_add : t -> key -> string -> root:B00_std.Fpath.t -> B00_std.Fpath.t list -> (bool, string) result

manifest_add c k m ~root fs is like add except it also stores the file paths fs relativized with respect to root. This means the actual file paths need not to be provided to revive the operation see manifest_revive. This errors if one of the files in fs is not prefixed by root.

val rem : t -> key -> (bool, string) result

rem c k removes the binding of k in c. Ok true is returned if k was bound in c and Ok false otherwise.

val find : t -> key -> ((B00_std.Fpath.t option * B00_std.Fpath.t * B00_std.Fpath.t list) option, string) result

find c k is Some (mf, m, fs) if k is bound in c with mf the file that holds the file manifest (if any), m the file that holds the key metadata and fs the files that hold the file contents of the key in the order given on add (or in the order of the manifest). The result is None if k is unbound in c.

val revive : t -> key -> B00_std.Fpath.t list -> (string option, string) result

revive c k fs binds the file contents of key k to the file paths fs. These file paths are overwritten if they exist and intermediate directories are created if needed (with permissions 0o755). The function returns:

  • Ok (Some m in case of success, with m the metadata of the key. In this case the files fs are guaranteed to exist and to match those of the key files in the order given on add.
  • Ok None if the length of fs does not match the sequence of files of k or if k is unbound in c. In this case the file paths fs are left untouched.
  • Error _ if an unexpected error occurs. In that case the resulting state of the file system for paths fs is undefined.
val manifest_revive : t -> key -> root:B00_std.Fpath.t -> ((B00_std.Fpath.t list * string) option, string) result

manifest_revive is like revive however the file paths that are written to are determined by the cache's file manifest whose path are made absolute using root and returned in the result. None is returned if the key existed but had no manifest.

val trim_size : ?is_unused:(key -> bool) -> t -> max_byte_size:int -> pct:int -> (unit, string) result

trim_size c ~is_unused max_byte_size ~pct deletes keys of c until the cache either weights at most max_byte_size or is pct of its current size; whichever is the smaller. The function deletes by order of increasing key access time (see key_stats) but unused keys determined by is_unused are deleted first (defaults to fun _ -> false).