1995-08-09 08:06:35 -07:00
|
|
|
(***********************************************************************)
|
|
|
|
(* *)
|
1996-04-30 07:53:58 -07:00
|
|
|
(* Objective Caml *)
|
1995-08-09 08:06:35 -07:00
|
|
|
(* *)
|
|
|
|
(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
|
|
|
|
(* *)
|
1996-04-30 07:53:58 -07:00
|
|
|
(* Copyright 1996 Institut National de Recherche en Informatique et *)
|
1999-11-17 10:59:06 -08:00
|
|
|
(* en Automatique. All rights reserved. This file is distributed *)
|
|
|
|
(* under the terms of the GNU Library General Public License. *)
|
1995-08-09 08:06:35 -07:00
|
|
|
(* *)
|
|
|
|
(***********************************************************************)
|
|
|
|
|
|
|
|
(* $Id$ *)
|
|
|
|
|
1995-08-09 06:15:01 -07:00
|
|
|
(* Module [Hashtbl]: hash tables and hash functions *)
|
1995-05-04 03:15:53 -07:00
|
|
|
|
|
|
|
(* Hash tables are hashed association tables, with in-place modification. *)
|
|
|
|
|
1996-10-31 08:03:04 -08:00
|
|
|
(*** Generic interface *)
|
|
|
|
|
1995-05-04 03:15:53 -07:00
|
|
|
type ('a, 'b) t
|
|
|
|
(* The type of hash tables from type ['a] to type ['b]. *)
|
|
|
|
|
2000-04-02 18:57:52 -07:00
|
|
|
val create : int -> ('a,'b) t
|
1996-04-22 04:15:41 -07:00
|
|
|
(* [Hashtbl.create n] creates a new, empty hash table, with
|
2000-01-13 11:04:16 -08:00
|
|
|
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. *)
|
1995-05-04 03:15:53 -07:00
|
|
|
|
|
|
|
val clear : ('a, 'b) t -> unit
|
|
|
|
(* Empty a hash table. *)
|
|
|
|
|
1999-11-30 08:07:38 -08:00
|
|
|
val add : ('a, 'b) t -> key:'a -> data:'b -> unit
|
1995-08-09 06:15:01 -07:00
|
|
|
(* [Hashtbl.add tbl x y] adds a binding of [x] to [y] in table [tbl].
|
1995-05-04 03:15:53 -07:00
|
|
|
Previous bindings for [x] are not removed, but simply
|
1998-04-27 02:55:50 -07:00
|
|
|
hidden. That is, after performing [Hashtbl.remove tbl x],
|
|
|
|
the previous binding for [x], if any, is restored.
|
|
|
|
(Same behavior as with association lists.) *)
|
1995-05-04 03:15:53 -07:00
|
|
|
|
2000-04-02 18:57:52 -07:00
|
|
|
val find : ('a, 'b) t -> 'a -> 'b
|
1995-08-09 06:15:01 -07:00
|
|
|
(* [Hashtbl.find tbl x] returns the current binding of [x] in [tbl],
|
1995-05-04 03:15:53 -07:00
|
|
|
or raises [Not_found] if no such binding exists. *)
|
|
|
|
|
2000-04-02 18:57:52 -07:00
|
|
|
val find_all : ('a, 'b) t -> 'a -> 'b list
|
1995-08-09 06:15:01 -07:00
|
|
|
(* [Hashtbl.find_all tbl x] returns the list of all data
|
|
|
|
associated with [x] in [tbl].
|
|
|
|
The current binding is returned first, then the previous
|
1995-05-04 03:15:53 -07:00
|
|
|
bindings, in reverse order of introduction in the table. *)
|
|
|
|
|
2000-04-02 18:57:52 -07:00
|
|
|
val mem : ('a, 'b) t -> 'a -> bool
|
1999-02-11 01:46:14 -08:00
|
|
|
(* [Hashtbl.mem tbl x] checks if [x] is bound in [tbl]. *)
|
|
|
|
|
2000-04-02 18:57:52 -07:00
|
|
|
val remove : ('a, 'b) t -> 'a -> unit
|
1995-08-09 06:15:01 -07:00
|
|
|
(* [Hashtbl.remove tbl x] removes the current binding of [x] in [tbl],
|
1995-05-04 03:15:53 -07:00
|
|
|
restoring the previous binding if it exists.
|
|
|
|
It does nothing if [x] is not bound in [tbl]. *)
|
|
|
|
|
2000-07-28 05:24:25 -07:00
|
|
|
val replace : ('a, 'b) t -> key:'a -> data:'b -> unit
|
|
|
|
(* [Hashtbl.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 [Hashtbl.remove tbl x]
|
|
|
|
followed by [Hashtbl.add tbl x y]. *)
|
|
|
|
|
2000-04-02 18:57:52 -07:00
|
|
|
val iter : f:(key:'a -> data:'b -> unit) -> ('a, 'b) t -> unit
|
1997-10-31 04:59:29 -08:00
|
|
|
(* [Hashtbl.iter f tbl] applies [f] to all bindings in table [tbl].
|
1996-06-28 08:10:28 -07:00
|
|
|
[f] receives the key as first argument, and the associated value
|
1995-05-04 03:15:53 -07:00
|
|
|
as second argument. The order in which the bindings are passed to
|
1996-09-05 10:35:43 -07:00
|
|
|
[f] is unspecified. Each binding is presented exactly once
|
1995-05-04 03:15:53 -07:00
|
|
|
to [f]. *)
|
|
|
|
|
2001-06-25 01:33:25 -07:00
|
|
|
val fold : f:(key:'a -> data:'b -> 'c -> 'c) -> ('a, 'b) t -> init:'c -> 'c
|
|
|
|
(* [Hashtbl.fold f tbl init] computes
|
|
|
|
[(f kN dN ... (f k1 d1 init)...)],
|
|
|
|
where [k1 ... kN] are the keys of all bindings in [tbl],
|
|
|
|
and [d1 ... dN] are the associated values.
|
|
|
|
The order in which the bindings are passed to
|
|
|
|
[f] is unspecified. Each binding is presented exactly once
|
|
|
|
to [f]. *)
|
|
|
|
|
1996-10-31 08:03:04 -08:00
|
|
|
(*** Functorial interface *)
|
|
|
|
|
|
|
|
module type HashedType =
|
|
|
|
sig
|
|
|
|
type t
|
|
|
|
val equal: t -> t -> bool
|
|
|
|
val hash: t -> int
|
|
|
|
end
|
|
|
|
(* The input signature of the functor [Hashtbl.Make].
|
|
|
|
[t] is the type of keys.
|
|
|
|
[equal] is the equality predicate used to compare keys.
|
|
|
|
[hash] is a hashing function on keys, returning a non-negative
|
|
|
|
integer. It must be such that if two keys are equal according
|
|
|
|
to [equal], then they must have identical hash values as computed
|
|
|
|
by [hash].
|
|
|
|
Examples: suitable ([equal], [hash]) pairs for arbitrary key
|
|
|
|
types include
|
1998-04-27 02:55:50 -07:00
|
|
|
([(=)], [Hashtbl.hash]) for comparing objects by structure, and
|
1996-10-31 08:03:04 -08:00
|
|
|
([(==)], [Hashtbl.hash]) for comparing objects by addresses
|
|
|
|
(e.g. for mutable or cyclic keys). *)
|
|
|
|
|
|
|
|
module type S =
|
|
|
|
sig
|
|
|
|
type key
|
|
|
|
type 'a t
|
2000-04-02 18:57:52 -07:00
|
|
|
val create: int -> 'a t
|
1996-10-31 08:03:04 -08:00
|
|
|
val clear: 'a t -> unit
|
1999-11-30 08:07:38 -08:00
|
|
|
val add: 'a t -> key:key -> data:'a -> unit
|
2000-04-02 18:57:52 -07:00
|
|
|
val remove: 'a t -> key -> unit
|
|
|
|
val find: 'a t -> key -> 'a
|
|
|
|
val find_all: 'a t -> key -> 'a list
|
2000-07-28 05:24:25 -07:00
|
|
|
val replace : 'a t -> key:key -> data:'a -> unit
|
2000-04-02 18:57:52 -07:00
|
|
|
val mem: 'a t -> key -> bool
|
|
|
|
val iter: f:(key:key -> data:'a -> unit) -> 'a t -> unit
|
2001-06-25 01:33:25 -07:00
|
|
|
val fold: f:(key:key -> data:'a -> 'b -> 'b) -> 'a t -> init:'b -> 'b
|
1996-10-31 08:03:04 -08:00
|
|
|
end
|
|
|
|
|
|
|
|
module Make(H: HashedType): (S with type key = H.t)
|
|
|
|
|
|
|
|
(* The functor [Hashtbl.Make] returns a structure containing
|
|
|
|
a type [key] of keys and a type ['a t] of hash tables
|
|
|
|
associating data of type ['a] to keys of type [key].
|
|
|
|
The operations perform similarly to those of the generic
|
|
|
|
interface, but use the hashing and equality functions
|
|
|
|
specified in the functor argument [H] instead of generic
|
|
|
|
equality and hashing. *)
|
|
|
|
|
1995-05-04 03:15:53 -07:00
|
|
|
(*** The polymorphic hash primitive *)
|
|
|
|
|
|
|
|
val hash : 'a -> int
|
1996-06-28 08:10:28 -07:00
|
|
|
(* [Hashtbl.hash x] associates a positive integer to any value of
|
1995-05-04 03:15:53 -07:00
|
|
|
any type. It is guaranteed that
|
|
|
|
if [x = y], then [hash x = hash y].
|
|
|
|
Moreover, [hash] always terminates, even on cyclic
|
|
|
|
structures. *)
|
|
|
|
|
1995-07-25 04:39:02 -07:00
|
|
|
external hash_param : int -> int -> 'a -> int = "hash_univ_param" "noalloc"
|
1996-06-28 08:10:28 -07:00
|
|
|
(* [Hashtbl.hash_param n m x] computes a hash value for [x], with the
|
1995-05-04 03:15:53 -07:00
|
|
|
same properties as for [hash]. The two extra parameters [n] and
|
|
|
|
[m] give more precise control over hashing. Hashing performs a
|
|
|
|
depth-first, right-to-left traversal of the structure [x], stopping
|
|
|
|
after [n] meaningful nodes were encountered, or [m] nodes,
|
|
|
|
meaningful or not, were encountered. Meaningful nodes are: integers;
|
|
|
|
floating-point numbers; strings; characters; booleans; and constant
|
1996-06-28 08:10:28 -07:00
|
|
|
constructors. Larger values of [m] and [n] means that more
|
1995-05-04 03:15:53 -07:00
|
|
|
nodes are taken into account to compute the final hash
|
1996-06-28 08:10:28 -07:00
|
|
|
value, and therefore collisions are less likely to happen.
|
1995-05-04 03:15:53 -07:00
|
|
|
However, hashing takes longer. The parameters [m] and [n]
|
|
|
|
govern the tradeoff between accuracy and speed. *)
|