1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
(** This module provides a kind of hash tables where each key is
present only once in the table, as opposed to the naive usage of
the standard [Hashtbl] module.
Its main purpose is to provide efficient implementation
of functions such as [list_keys] with enhanced safety
over the direct use of an [('a, 'b list ref) Hashtbl.t] type.
Many functions have two variants:
- the first one is applied only on the current bindings, like
[iter].
- the second one has the [_all] suffix like [iter_all]
and is applied to the list of
all the values that are bound to the given key
instead of only to the topmost value.
This list of values
is prebuilt, so there is no cost for building the list when
such a function is applied.
Example - clustering elements:
[Hashtbl2.list_all (Hashtbl2.of_list 10 [ (1, "a"); (2, "b"); (1, "c") ])]
returns [[(2, ["b"]); (1, ["c"; "a"])]].
[Hashtbl2] is an additional layer over the standard [Hashtbl] module.
@author Martin Jambon *)
type ('a, 'b) t
(** The type of hash tables from type ['a] to type ['b].
This representation is suitable for clustering elements
according to the given keys. *)
val create : int -> ('a, 'b) t
(** [Hashtbl2.create n] creates a new, empty hash table, with
initial size [n]. For best results, [n] should be on the
order of the expected number of elements that will be in
the table. The table grows as needed, so [n] is just an
initial guess. *)
val clear : ('a, 'b) t -> unit
(** Empty a hash table. *)
val add : ('a, 'b) t -> 'a -> 'b -> unit
(** [Hashtbl2.add tbl x y] adds a binding of [x] to [y] in table [tbl].
Previous bindings for [x] are not removed, but simply
hidden. That is, after performing {!Hashtbl2.remove}[ tbl x],
the previous binding for [x], if any, is restored.
(Same behavior as with association lists.) *)
val copy : ('a, 'b) t -> ('a, 'b) t
(** Return a copy of the given hashtable. *)
val find : ('a, 'b) t -> 'a -> 'b
(** [Hashtbl2.find tbl x] returns the current binding of [x] in [tbl],
or raises [Not_found] if no such binding exists. *)
val find_all : ('a, 'b) t -> 'a -> 'b list
(** [Hashtbl2.find_all tbl x] returns the list of all data
associated with [x] in [tbl].
The current binding is returned first, then the previous
bindings, in reverse order of introduction in the table. *)
val mem : ('a, 'b) t -> 'a -> bool
(** [Hashtbl2.mem tbl x] checks if [x] is bound in [tbl]. *)
val remove : ('a, 'b) t -> 'a -> unit
(** [Hashtbl2.remove tbl x] removes the current binding of [x] in [tbl],
restoring the previous binding if it exists.
It does nothing if [x] is not bound in [tbl]. *)
val remove_all : ('a, 'b) t -> 'a -> unit
(** [Hashtbl2.remove_all tbl x] removes all bindings of [x] in [tbl].
It does nothing if [x] is not bound in [tbl]. *)
val replace : ('a, 'b) t -> 'a -> 'b -> unit
(** [Hashtbl2.replace tbl x y] replaces the current binding of [x]
in [tbl] by a binding of [x] to [y]. If [x] is unbound in [tbl],
a binding of [x] to [y] is added to [tbl].
This is functionally equivalent to {!Hashtbl2.remove}[ tbl x]
followed by {!Hashtbl2.add}[ tbl x y]. *)
val replace_all : ('a, 'b) t -> 'a -> 'b list -> unit
(** [Hashtbl2.replace_all tbl x y] replaces all bindings of [x]
in [tbl] by bindings of [x] to the elements of [y].
The first element of [y] defines the current binding,
the second element is the defined the previous binding, and so on. *)
val iter : ('a -> 'b -> unit) -> ('a, 'b) t -> unit
(** [Hashtbl2.iter f tbl] applies [f] to current bindings in table [tbl].
[f] receives the key as first argument, and the associated value
as second argument. Each current binding is presented exactly once to [f].
Hidden bindings are ignored.
The order in which the bindings are passed to [f] is unspecified. *)
val iter_all : ('a -> 'b list -> unit) -> ('a, 'b) t -> unit
(** [Hashtbl2.iter_all f tbl] applies [f] to all bindings in table [tbl].
[f] receives the key as first argument, and all the associated values
as second argument in reverse order of introduction in the table.
The order in which the bindings are passed to [f] is unspecified. *)
val fold : ('a -> 'b -> 'c -> 'c) -> ('a, 'b) t -> 'c -> 'c
(** [Hashtbl2.fold f tbl init] computes
[(f kN dN ... (f k1 d1 init)...)],
where [k1 ... kN] are the keys of current bindings in [tbl],
and [d1 ... dN] are the associated values.
Each current binding is presented exactly once to [f].
Hidden bindings are ignored. *)
val fold_all : ('a -> 'b list -> 'c -> 'c) -> ('a, 'b) t -> 'c -> 'c
(** [Hashtbl2.fold_all f tbl init] computes
[(f kN lN ... (f k1 l1 init)...)],
where [k1 ... kN] are the keys of all bindings in [tbl],
and [l1 ... lN] are the lists of associated values, in reverse order
of introduction in the table. *)
val list_keys : ('a, 'b) t -> 'a list
(** [Hashtbl2.list_keys tbl] returns a list of all the keys
from the current bindings. Therefore no key is duplicated.
Order is unspecified. *)
val list_values : ('a, 'b) t -> 'b list
(** [Hashtbl2.list_values tbl] returns a list of all the values
from the current bindings. Hidden bindings are ignored.
Order is unspecified. *)
val list_all_values : ('a, 'b) t -> 'b list list
(** [Hashtbl2.list_all_values tbl] returns a list of all the values
from all bindings. Order is unspecified. *)
val list : ('a, 'b) t -> ('a * 'b) list
(** [Hashtbl2.list tbl] returns a list of the current bindings.
Order is unspecified. *)
val list_all : ('a, 'b) t -> ('a * 'b list) list
(** [Hashtbl2.list_all tbl] returns a list of all the bindings clustered
according to their key. Order is unspecified. *)
val of_list : int -> ('a * 'b) list -> ('a, 'b) t
(** [Hashtbl2.of_list n l] converts a list of bindings into
a hash table of initial size [n]. The ordering of the list is the order
of introduction of the bindings in the table. *)
val of_keys : int -> 'a list -> ('a, unit) t
(** [Hashtbl2.of_keys n l] converts a list of elements into
a hash table of initial size [n] containing unique copies of these
elements bound at most one time to [()]. *)
|