disk_persistence.mli
(*****************************************************************************)
(* *)
(* Open Source License *)
(* Copyright (c) 2022 Nomadic Labs, <contact@nomadic-labs.com> *)
(* *)
(* Permission is hereby granted, free of charge, to any person obtaining a *)
(* copy of this software and associated documentation files (the "Software"),*)
(* to deal in the Software without restriction, including without limitation *)
(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *)
(* and/or sell copies of the Software, and to permit persons to whom the *)
(* Software is furnished to do so, subject to the following conditions: *)
(* *)
(* The above copyright notice and this permission notice shall be included *)
(* in all copies or substantial portions of the Software. *)
(* *)
(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)
(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *)
(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *)
(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)
(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *)
(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *)
(* DEALINGS IN THE SOFTWARE. *)
(* *)
(*****************************************************************************)
type error +=
| Cannot_write_file of string
| Cannot_create_dir of string
| Cannot_read_file of string
| Io_error of [`Close | `Open] Lwt_utils_unix.io_error
| Unix_error of Unix.error
| Decoding_error of Data_encoding.Binary.read_error
(** Signature for hash tables with additional information *)
module type H = sig
include Hashtbl.SeededS
(** Type of values *)
type value
(** Name used to derive a path (relative to [data_dir] in [load_from_disk]) of
where to store the persistent information for this hash table. *)
val name : string
(** String version of key (used for filenames). *)
val string_of_key : key -> string
(** Parse a key. We must have [key_of_string (string_of_key k) = k]. *)
val key_of_string : string -> key option
(** Encoding for values (only the binary encoding is used *)
val value_encoding : value Data_encoding.t
end
(** Create an on-disk persistent version of {!Hashtbl}. *)
module Make_table (H : H) : sig
type key = H.key
type value = H.value
(** Type of persistent hash tables *)
type t
(** Persistent version of {!H.replace} *)
val replace : t -> key -> value -> unit tzresult Lwt.t
(** Persistent version of {!H.remove} *)
val remove : t -> key -> unit tzresult Lwt.t
(** Same as {!H.find} *)
val find : t -> key -> value option
(** Same as {!H.mem} *)
val mem : t -> key -> bool
(** Same as {!H.iter_s} *)
val iter_s : (key -> value -> unit Lwt.t) -> t -> unit Lwt.t
(** Same as {!H.iter_es} *)
val iter_es :
(key -> value -> unit tzresult Lwt.t) -> t -> unit tzresult Lwt.t
(** Same as {!H.length} *)
val length : t -> int
(** Persistent version of {!H.replace_seq} *)
val replace_seq : t -> (key * value) Seq.t -> unit tzresult Lwt.t
(** [load_from_disk ~warn_unreadable ~initial_size ~data_dir] creates a hash
table of size [initial_size]. The hash table is populated by persistent
elements present in [data_dir/H.name] which pass the [filter] (the
directory is created if it does not exist). If [warn_unreadable] is [Some
warn], unreadable files are ignored but a warning is printed with [warn],
otherwise the loading fails on the first unreadable file. *)
val load_from_disk :
warn_unreadable:(string -> error trace -> unit Lwt.t) option ->
initial_size:int ->
data_dir:string ->
filter:(value -> bool) ->
t tzresult Lwt.t
end
(** Create an on-disk persistent version of the {!Hash_queue} data structure. *)
module Make_queue (N : sig
(** Name used to derive a path (relative to [data_dir] in [load_from_disk]) of where
to store the persistent information for this queue. *)
val name : string
end)
(K : Tezos_crypto.S.HASH) (V : sig
type t
val encoding : t Data_encoding.t
end) : sig
type t
(** [remove q k] removes the binding from [k] in [q]. If [k] is not bound in
[c], it does nothing. The removal is persisted on disk. *)
val remove : t -> K.t -> unit tzresult Lwt.t
(** [replace q k v] binds the key [k] to the value [v] in the queue [q]. This
may or may not cause another binding to be removed, depending on the
number of bindings already present in [q]. The addition (or replacement)
is persisted on disk. *)
val replace : t -> K.t -> V.t -> unit tzresult Lwt.t
(** [fold f q init] folds the function [f] over the bindings
of [q] (in memory). The elements are iterated from oldest to newest. *)
val fold : (K.t -> V.t -> 'a -> 'a) -> t -> 'a -> 'a
(** [length q] is the number of bindings held by [q]. *)
val length : t -> int
(** [load_from_disk ~warn_unreadable ~capacity ~data_dir ~filter] creates a
bounded hash queue of capacity [capacity]. The queue is populated by
persistent elements present in [data_dir/N.name] which pass the [filter]
(the directory is created if it does not exist). If [warn_unreadable] is
[Some warn], unreadable files are ignored but a warning is printed with
[warn], otherwise the loading fails on the first unreadable file. *)
val load_from_disk :
warn_unreadable:(string -> error trace -> unit Lwt.t) option ->
capacity:int ->
data_dir:string ->
filter:(V.t -> bool) ->
t tzresult Lwt.t
end