Module Weak_hashtbl
A hashtable that keeps a weak pointer to each key's data and uses a finalizer to detect when the data is no longer referenced (by any non-weak pointers).
Once a key's data is finalized, the table will effectively behave as if the key is not in the table, e.g., find will return None. However, one must call reclaim_space_for_keys_with_unused_data to actually reclaim the space used by the table for such keys.
Unlike (OCaml's) Weak.Make, which also describes itself as a "weak hashtable," Weak_hashtbl gives a dictionary-style structure. In fact, OCaml's Weak.Make may better be described as a weak set.
There's a tricky type of bug one can write with this module, e.g.:
type t =
{ foo : string
; bar : float Incr.t
}
let tbl = Weak_hashtbl.create ()
let x1 =
let t = Weak_hashtbl.find_or_add tbl key ~default:(fun () ->
(... some function that computes a t...))
in
t.barAt this point, the data associated with key is unreachable (since all we did with it was project out field bar), so it may disappear from the table at any time.
val sexp_of_t : ('a -> Ppx_sexp_conv_lib.Sexp.t) -> ('b -> Ppx_sexp_conv_lib.Sexp.t) -> ('a, 'b) t -> Ppx_sexp_conv_lib.Sexp.t
val create : ?growth_allowed:bool -> ?size:int -> (module Weak_hashtbl__.Import.Hashtbl.Key_plain with type t = 'a) -> ('a, 'b) tgrowth_allowedandsizeare both optionally passed on to the underlying call toHashtbl.create.
module Using_hashable : sig ... endval mem : ('a, _) t -> 'a -> boolval find : ('a, 'b) t -> 'a -> 'b Weak_hashtbl__.Import.Heap_block.t optionval find_or_add : ('a, 'b) t -> 'a -> default:(unit -> 'b Weak_hashtbl__.Import.Heap_block.t) -> 'b Weak_hashtbl__.Import.Heap_block.tval remove : ('a, 'b) t -> 'a -> unitval add_exn : ('a, 'b) t -> key:'a -> data:'b Weak_hashtbl__.Import.Heap_block.t -> unitval replace : ('a, 'b) t -> key:'a -> data:'b Weak_hashtbl__.Import.Heap_block.t -> unitval key_is_using_space : ('a, _) t -> 'a -> boolkey_is_using_space t keyreturnstrueifkeyis using some space int.mem t keyimplieskey_is_using_space t key, but it is also possible that thatkey_is_using_space t key && not (mem t key).
val reclaim_space_for_keys_with_unused_data : (_, _) t -> unitreclaim_space_for_keys_with_unused_data treclaims space for all keys intwhose data has been detected (by a finalizer) to be unused. Onlykeys such thatkey_is_using_space t key && not (mem t key)will be reclaimed.
val set_run_when_unused_data : (_, _) t -> thread_safe_f:(unit -> unit) -> unitset_run_when_unused_data t ~thread_safe_fcallsthread_safe_fin the finalizer attached to eachdataint, after ensuring the entry being finalized will be handled in the next call toreclaim_space_for_keys_with_unused_data. This can be used to arrange to callreclaim_space_for_keys_with_unused_dataat a convenient time in the future.thread_safe_fmust be thread safe -- it is not safe for it to call anyWeak_hashtblfunctions.