ocaml-containers/src/data/CCHashTrie.mli

163 lines
4.6 KiB
OCaml

(* This file is free software, part of containers. See file "license" for more details. *)
(** Hash Tries
Trie indexed by the hash of the keys, where the branching factor is fixed.
The goal is to have a quite efficient functional structure with fast
update and access {b if} the hash function is good.
The trie is not binary, to improve cache locality and decrease depth.
Preliminary benchmarks (see the "tbl" section of benchmarks) tend to show
that this type is quite efficient for small data sets.
{b status: unstable}
@since 0.13
*)
type 'a iter = ('a -> unit) -> unit
type 'a gen = unit -> 'a option
type 'a printer = Format.formatter -> 'a -> unit
type 'a ktree = unit -> [`Nil | `Node of 'a * 'a ktree list]
(** {2 Transient Identifiers} *)
module Transient : sig
type t
(** Identifiers for transient modifications. A transient modification
is uniquely identified by a [Transient.t]. Once [Transient.freeze r]
is called, [r] cannot be used to modify the structure again. *)
val create : unit -> t
(** Create a new, active ID. *)
val equal : t -> t -> bool
(** Equality between IDs. *)
val frozen : t -> bool
(** [frozen i] returns [true] if [freeze i] was called before. In this case,
the ID cannot be used for modifications again. *)
val active : t -> bool
(** [active i] is [not (frozen i)]. *)
val freeze : t -> unit
(** [freeze i] makes [i] unusable for new modifications. The values
created with [i] will now be immutable. *)
val with_ : (t -> 'a) -> 'a
(** [with_ f] creates a transient ID [i], calls [f i],
freezes the ID [i] and returns the result of [f i]. *)
exception Frozen
(** Raised when a frozen ID is used. *)
end
(** {2 Signature} *)
module type S = sig
type key
type 'a t
val empty : 'a t
val is_empty : _ t -> bool
val singleton : key -> 'a -> 'a t
val add : key -> 'a -> 'a t -> 'a t
val mem : key -> _ t -> bool
val get : key -> 'a t -> 'a option
val get_exn : key -> 'a t -> 'a
(** @raise Not_found if key not present. *)
val remove : key -> 'a t -> 'a t
(** Remove the key, if present. *)
val update : key -> f:('a option -> 'a option) -> 'a t -> 'a t
(** [update k ~f m] calls [f (Some v)] if [get k m = Some v], [f None]
otherwise. Then, if [f] returns [Some v'] it binds [k] to [v'],
if [f] returns [None] it removes [k]. *)
val add_mut : id:Transient.t -> key -> 'a -> 'a t -> 'a t
(** [add_mut ~id k v m] behaves like [add k v m], except it will mutate
in place whenever possible. Changes done with an [id] might affect all
versions of the structure obtained with the same [id] (but not
other versions).
@raise Transient.Frozen if [id] is frozen. *)
val remove_mut : id:Transient.t -> key -> 'a t -> 'a t
(** Same as {!remove}, but modifies in place whenever possible.
@raise Transient.Frozen if [id] is frozen. *)
val update_mut : id:Transient.t -> key -> f:('a option -> 'a option) -> 'a t -> 'a t
(** Same as {!update} but with mutability.
@raise Transient.Frozen if [id] is frozen. *)
val cardinal : _ t -> int
val choose : 'a t -> (key * 'a) option
val choose_exn : 'a t -> key * 'a
(** @raise Not_found if not pair was found. *)
val iter : f:(key -> 'a -> unit) -> 'a t -> unit
val fold : f:('b -> key -> 'a -> 'b) -> x:'b -> 'a t -> 'b
(** {5 Conversions} *)
val to_list : 'a t -> (key * 'a) list
val add_list : 'a t -> (key * 'a) list -> 'a t
val add_list_mut : id:Transient.t -> 'a t -> (key * 'a) list -> 'a t
(** @raise Frozen if the ID is frozen. *)
val of_list : (key * 'a) list -> 'a t
val add_iter : 'a t -> (key * 'a) iter -> 'a t
val add_iter_mut : id:Transient.t -> 'a t -> (key * 'a) iter -> 'a t
(** @raise Frozen if the ID is frozen. *)
val of_iter : (key * 'a) iter -> 'a t
val to_iter : 'a t -> (key * 'a) iter
val add_gen : 'a t -> (key * 'a) gen -> 'a t
val add_gen_mut : id:Transient.t -> 'a t -> (key * 'a) gen -> 'a t
(** @raise Frozen if the ID is frozen. *)
val of_gen : (key * 'a) gen -> 'a t
val to_gen : 'a t -> (key * 'a) gen
(** {5 IO} *)
val pp : key printer -> 'a printer -> 'a t printer
(** Renamed from [val print].
@since 2.0 *)
val as_tree : 'a t -> [`L of int * (key * 'a) list | `N ] ktree
(** For debugging purpose: explore the structure of the tree,
with [`L (h,l)] being a leaf (with shared hash [h])
and [`N] an inner node. *)
end
(** {2 Type for keys} *)
module type KEY = sig
type t
val equal : t -> t -> bool
val hash : t -> int
end
(** {2 Functors} *)
module Make(K : KEY) : S with type key = K.t
(**/**)
val popcount : int64 -> int
(**/**)