package core_kernel
Industrial strength alternative to OCaml's standard library
Install
Dune Dependency
Authors
Maintainers
Sources
core_kernel-v0.16.0.tar.gz
sha256=e37370bad978cfb71fdaf2b1a25ab1506b98ef0b91e0dbd189ffd9d853245ce2
doc/src/core_kernel.weak_hashtbl/weak_hashtbl.ml.html
Source file weak_hashtbl.ml
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
open! Base type ('a, 'b) t = { entry_by_key : ('a, 'b Weak_pointer.t) Hashtbl.t ; keys_with_unused_data : 'a Thread_safe_queue.t ; mutable thread_safe_run_when_unused_data : unit -> unit } [@@deriving sexp_of] module Using_hashable = struct let create ?growth_allowed ?size hashable = { entry_by_key = Hashtbl.create ?growth_allowed ?size (Base.Hashable.to_key hashable) ; keys_with_unused_data = Thread_safe_queue.create () ; thread_safe_run_when_unused_data = ignore } ;; end let create ?growth_allowed ?size m = Using_hashable.create ?growth_allowed ?size (Hashable.of_key m) ;; let set_run_when_unused_data t ~thread_safe_f = t.thread_safe_run_when_unused_data <- thread_safe_f; ;; let remove t key = Hashtbl.remove t.entry_by_key key (* In order for a call to [reclaim_space_for_keys_with_unused_data] to reclaim a key that was previously finalized, the weak pointer must have been cleared. This relies on the fact that the OCaml garbage collector clears weaks and then runs finalizers. *) let reclaim_space_for_keys_with_unused_data t = while Thread_safe_queue.length t.keys_with_unused_data > 0 do let key = Thread_safe_queue.dequeue_exn t.keys_with_unused_data in match Hashtbl.find t.entry_by_key key with | None -> () | Some entry -> if Weak_pointer.is_none entry then remove t key done; ;; let get_entry t key = Hashtbl.find_or_add t.entry_by_key key ~default:(fun () -> Weak_pointer.create ()); ;; let mem t key = match Hashtbl.find t.entry_by_key key with | None -> false | Some entry -> Weak_pointer.is_some entry ;; let key_is_using_space t key = Hashtbl.mem t.entry_by_key key let set_data t key entry (data : _ Heap_block.t) = Weak_pointer.set entry data; let cleanup () = Exn.handle_uncaught_and_exit (fun () -> Thread_safe_queue.enqueue t.keys_with_unused_data key; t.thread_safe_run_when_unused_data ()) in try Stdlib.Gc.finalise_last cleanup data with (* In this case, [x] is known to be static data, which will never be collected by the GC anyway, so it's safe to drop *) | Invalid_argument _ -> () ;; let replace t ~key ~data = set_data t key (get_entry t key) data let add_exn t ~key ~data = let entry = get_entry t key in if Weak_pointer.is_some entry then Error.raise_s [%message "Weak_hashtbl.add_exn of key in use" ~_:(t : (_, _) t) [%here]]; set_data t key entry data; ;; let find t key = match Hashtbl.find t.entry_by_key key with | None -> None | Some entry -> Weak_pointer.get entry ;; let find_or_add t key ~default = let entry = get_entry t key in match Weak_pointer.get entry with | Some v -> v | None -> let data = default () in set_data t key entry data; data ;;
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>