A polymorphic hashtbl that uses Pool to avoid allocation.
This uses the standard linked-chain hashtable algorithm, albeit with links performed
through a pool and hence avoiding caml_modify (for table manipulation), even when
hashing object keys/values.
This implementation is worth exploring for your application if profiling demonstrates
that garbage collection and the caml_modify write barrier are a significant part of
your execution time.
include Hashtbl_intf.Hashtblval sexp_of_t : ('a ‑> Base.Sexp.t) ‑> ('b ‑> Base.Sexp.t) ‑> ('a, 'b) t ‑> Base.Sexp.tval invariant : 'a Base__.Invariant_intf.inv ‑> 'b Base__.Invariant_intf.inv ‑> ('a, 'b) t Base__.Invariant_intf.invval create : ?growth_allowed:bool ‑> ?size:int ‑> (module Base__.Hashtbl_intf.Key with type t = 'a) ‑> ('a, 'b) tval of_alist : ?growth_allowed:bool ‑> ?size:int ‑> (module Base__.Hashtbl_intf.Key with type t = 'a) ‑> ('a * 'b) list ‑> [ `Duplicate_key of 'a | `Ok of ('a, 'b) t ]val of_alist_report_all_dups : ?growth_allowed:bool ‑> ?size:int ‑> (module Base__.Hashtbl_intf.Key with type t = 'a) ‑> ('a * 'b) list ‑> [ `Duplicate_keys of 'a list | `Ok of ('a, 'b) t ]val of_alist_or_error : ?growth_allowed:bool ‑> ?size:int ‑> (module Base__.Hashtbl_intf.Key with type t = 'a) ‑> ('a * 'b) list ‑> ('a, 'b) t Base.Or_error.tval of_alist_exn : ?growth_allowed:bool ‑> ?size:int ‑> (module Base__.Hashtbl_intf.Key with type t = 'a) ‑> ('a * 'b) list ‑> ('a, 'b) tval of_alist_multi : ?growth_allowed:bool ‑> ?size:int ‑> (module Base__.Hashtbl_intf.Key with type t = 'a) ‑> ('a * 'b) list ‑> ('a, 'b list) tval create_mapped : ?growth_allowed:bool ‑> ?size:int ‑> (module Base__.Hashtbl_intf.Key with type t = 'a) ‑> get_key:('r ‑> 'a) ‑> get_data:('r ‑> 'b) ‑> 'r list ‑> [ `Duplicate_keys of 'a list | `Ok of ('a, 'b) t ]val create_with_key : ?growth_allowed:bool ‑> ?size:int ‑> (module Base__.Hashtbl_intf.Key with type t = 'a) ‑> get_key:('r ‑> 'a) ‑> 'r list ‑> [ `Duplicate_keys of 'a list | `Ok of ('a, 'r) t ]val create_with_key_or_error : ?growth_allowed:bool ‑> ?size:int ‑> (module Base__.Hashtbl_intf.Key with type t = 'a) ‑> get_key:('r ‑> 'a) ‑> 'r list ‑> ('a, 'r) t Base.Or_error.tval create_with_key_exn : ?growth_allowed:bool ‑> ?size:int ‑> (module Base__.Hashtbl_intf.Key with type t = 'a) ‑> get_key:('r ‑> 'a) ‑> 'r list ‑> ('a, 'r) tval group : ?growth_allowed:bool ‑> ?size:int ‑> (module Base__.Hashtbl_intf.Key with type t = 'a) ‑> get_key:('r ‑> 'a) ‑> get_data:('r ‑> 'b) ‑> combine:('b ‑> 'b ‑> 'b) ‑> 'r list ‑> ('a, 'b) tval sexp_of_key : ('a, 'b) t ‑> 'a key ‑> Base.Sexp.tval clear : ('a, 'b) t ‑> unitval iter : ('a, 'b) t ‑> f:('b ‑> unit) ‑> unitval exists : ('a, 'b) t ‑> f:('b ‑> bool) ‑> boolval for_all : ('a, 'b) t ‑> f:('b ‑> bool) ‑> boolval count : ('a, 'b) t ‑> f:('b ‑> bool) ‑> intval length : ('a, 'b) t ‑> intval is_empty : ('a, 'b) t ‑> boolval merge_into : src:('k, 'a) t ‑> dst:('k, 'b) t ‑> f:(key:'k key ‑> 'a ‑> 'b option ‑> 'b merge_into_action) ‑> unitval data : ('a, 'b) t ‑> 'b listval filter_inplace : ('a, 'b) t ‑> f:('b ‑> bool) ‑> unitval map_inplace : ('a, 'b) t ‑> f:('b ‑> 'b) ‑> unitval filter_map_inplace : ('a, 'b) t ‑> f:('b ‑> 'b option) ‑> unitval validate : name:('a key ‑> string) ‑> 'b Base.Validate.check ‑> ('a, 'b) t Base.Validate.checkval hashable_s : ('key, 'a) t ‑> (module Base__.Hashtbl_intf.Key with type t = 'key)module Using_hashable : sig ... endmodule Poly : sig ... endmodule type Key_plain = Hashtbl_intf.Key_plainmodule type Key = Hashtbl_intf.Keymodule type Key_binable = Hashtbl_intf.Key_binablemodule type S_plain : Hashtbl_intf.S_plain with type ('a, 'b) hashtbl = ('a, 'b) tmodule type S : Hashtbl_intf.S with type ('a, 'b) hashtbl = ('a, 'b) tmodule type S_binable : Hashtbl_intf.S_binable with type ('a, 'b) hashtbl = ('a, 'b) tmodule Make_binable : functor (Key : Key_binable) -> S_binable with type key = Key.tmodule Hashable = Hashtbl_intf.Hashableval hashable : ('key, _) t ‑> 'key Hashable.tval iter_vals : (_, 'b) t ‑> f:('b ‑> Core_kernel__.Import.unit) ‑> Core_kernel__.Import.unitval replace : ('a, 'b) t ‑> key:'a key ‑> data:'b ‑> Core_kernel__.Import.unitval replace_all : (_, 'b) t ‑> f:('b ‑> 'b) ‑> Core_kernel__.Import.unitval replace_alli : ('a, 'b) t ‑> f:(key:'a key ‑> data:'b ‑> 'b) ‑> Core_kernel__.Import.unitval filter_replace_all : (_, 'b) t ‑> f:('b ‑> 'b Core_kernel__.Import.option) ‑> Core_kernel__.Import.unitval filter_replace_alli : ('a, 'b) t ‑> f:(key:'a key ‑> data:'b ‑> 'b Core_kernel__.Import.option) ‑> Core_kernel__.Import.unitval resize : (_, _) t ‑> Core_kernel__.Import.int ‑> Core_kernel__.Import.unitresize t size ensures that t can hold at least size entries without resizing
(again), provided that t has growth enabled. This is useful for sizing global
tables during application initialization, to avoid subsequent, expensive growth
online. See Zero.Immediate.String.resize, for example.
val on_grow : before:(Core_kernel__.Import.unit ‑> 'a) ‑> after:('a ‑> old_capacity:Core_kernel__.Import.int ‑> new_capacity:Core_kernel__.Import.int ‑> Core_kernel__.Import.unit) ‑> Core_kernel__.Import.uniton_grow ~before ~after allows you to connect higher level loggers to the point where
these hashtbls grow. before is called before the table grows, and after after it.
This permits you to e.g. measure the time elapsed between the two.
This is only meant for debugging and profiling, e.g. note that once a callback is installed, there is no way to remove it.