Module Tuple_pool
module Tuple_type : sig ... endTuple-like types used in
Pool.
module type S = Tuple_pool__.Tuple_pool_intf.SThis uses a Uniform_array.t to implement the pool. We expose that Pointer.t is an int so that OCaml can avoid the write barrier, due to knowing that Pointer.t isn't an OCaml pointer.
module Slots : Tuple_type.Slotsmodule Slot : Tuple_type.Slotmodule Pointer : sig ... endtype 'slots tA pool.
'slotswill look like('a1, ..., 'an) Slots.tn, and the pool holds tuples of type'a1 * ... * 'an.
val sexp_of_t : ('slots -> Ppx_sexp_conv_lib.Sexp.t) -> 'slots t -> Ppx_sexp_conv_lib.Sexp.tval invariant : 'a Base__.Invariant_intf.inv -> 'a t Base__.Invariant_intf.invval pointer_is_valid : 'slots t -> 'slots Pointer.t -> boolpointer_is_valid t pointerreturnstrueiffpointerpoints to a live tuple int, i.e.pointeris not null, not free, and is in the range oft.A pointer might not be in the range of a pool if it comes from another pool for example. In this case unsafe_get/set functions would cause a segfault.
val id_of_pointer : 'slots t -> 'slots Pointer.t -> Pointer.Id.tid_of_pointer t pointerreturns an id that is unique for the lifetime ofpointer's tuple. When the tuple is freed, the id is no longer valid, andpointer_of_id_exnwill fail on it.Pointer.null ()has a distinct id from all non-null pointers.
val pointer_of_id_exn : 'slots t -> Pointer.Id.t -> 'slots Pointer.tpointer_of_id_exn t idreturns the pointer corresponding toid. It fails if the tuple corresponding toidwas alreadyfreed.
val create : ('tuple, 'a) Slots.t -> capacity:int -> dummy:'tuple -> ('tuple, 'a) Slots.t tcreate slots ~capacity ~dummycreates an empty pool that can hold up tocapacityN-tuples. The slots ofdummyare stored in free tuples.createraises ifcapacity < 0 || capacity > max_capacity ~slots_per_tuple.
val max_capacity : slots_per_tuple:int -> intmax_capacityreturns the maximum capacity allowed when creating a pool.
val capacity : 'a t -> intcapacityreturns the maximum number of tuples that the pool can hold.
val length : 'a t -> intlengthreturns the number of tuples currently in the pool.0 <= length t <= capacity t
val grow : ?capacity:int -> 'a t -> 'a tgrow t ~capacityreturns a new poolt'with the supplied capacity. The new pool is to be used as a replacement fort. All live tuples intare now live int', and valid pointers to tuples intare now valid pointers to the identical tuple int'. It is an error to usetafter callinggrow t.growraises if the supplied capacity isn't larger thancapacity t.
val is_full : 'a t -> boolis_full treturnstrueif no more tuples can be allocated int.
val free : 'slots t -> 'slots Pointer.t -> unitfree t pointerfrees the tuple pointed to bypointerfromt.
val unsafe_free : 'slots t -> 'slots Pointer.t -> unitunsafe_free t pointerfrees the tuple pointed to bypointerwithout checkingpointer_is_valid
val new1 : 'a0 Slots.t1 t -> 'a0 -> 'a0 Slots.t1 Pointer.tnew<N> t a0 ... a<N-1>returns a new tuple from the pool, with the tuple's slots initialized toa0...a<N-1>.newraises ifis_full t.
val new2 : ('a0, 'a1) Slots.t2 t -> 'a0 -> 'a1 -> ('a0, 'a1) Slots.t2 Pointer.tval new3 : ('a0, 'a1, 'a2) Slots.t3 t -> 'a0 -> 'a1 -> 'a2 -> ('a0, 'a1, 'a2) Slots.t3 Pointer.tval new4 : ('a0, 'a1, 'a2, 'a3) Slots.t4 t -> 'a0 -> 'a1 -> 'a2 -> 'a3 -> ('a0, 'a1, 'a2, 'a3) Slots.t4 Pointer.tval new5 : ('a0, 'a1, 'a2, 'a3, 'a4) Slots.t5 t -> 'a0 -> 'a1 -> 'a2 -> 'a3 -> 'a4 -> ('a0, 'a1, 'a2, 'a3, 'a4) Slots.t5 Pointer.tval new6 : ('a0, 'a1, 'a2, 'a3, 'a4, 'a5) Slots.t6 t -> 'a0 -> 'a1 -> 'a2 -> 'a3 -> 'a4 -> 'a5 -> ('a0, 'a1, 'a2, 'a3, 'a4, 'a5) Slots.t6 Pointer.tval new7 : ('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6) Slots.t7 t -> 'a0 -> 'a1 -> 'a2 -> 'a3 -> 'a4 -> 'a5 -> 'a6 -> ('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6) Slots.t7 Pointer.tval new8 : ('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6, 'a7) Slots.t8 t -> 'a0 -> 'a1 -> 'a2 -> 'a3 -> 'a4 -> 'a5 -> 'a6 -> 'a7 -> ('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6, 'a7) Slots.t8 Pointer.tval new9 : ('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6, 'a7, 'a8) Slots.t9 t -> 'a0 -> 'a1 -> 'a2 -> 'a3 -> 'a4 -> 'a5 -> 'a6 -> 'a7 -> 'a8 -> ('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6, 'a7, 'a8) Slots.t9 Pointer.tval new10 : ('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6, 'a7, 'a8, 'a9) Slots.t10 t -> 'a0 -> 'a1 -> 'a2 -> 'a3 -> 'a4 -> 'a5 -> 'a6 -> 'a7 -> 'a8 -> 'a9 -> ('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6, 'a7, 'a8, 'a9) Slots.t10 Pointer.tval new11 : ('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6, 'a7, 'a8, 'a9, 'a10) Slots.t11 t -> 'a0 -> 'a1 -> 'a2 -> 'a3 -> 'a4 -> 'a5 -> 'a6 -> 'a7 -> 'a8 -> 'a9 -> 'a10 -> ('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6, 'a7, 'a8, 'a9, 'a10) Slots.t11 Pointer.tval new12 : ('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6, 'a7, 'a8, 'a9, 'a10, 'a11) Slots.t12 t -> 'a0 -> 'a1 -> 'a2 -> 'a3 -> 'a4 -> 'a5 -> 'a6 -> 'a7 -> 'a8 -> 'a9 -> 'a10 -> 'a11 -> ('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6, 'a7, 'a8, 'a9, 'a10, 'a11) Slots.t12 Pointer.tval new13 : ('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6, 'a7, 'a8, 'a9, 'a10, 'a11, 'a12) Slots.t13 t -> 'a0 -> 'a1 -> 'a2 -> 'a3 -> 'a4 -> 'a5 -> 'a6 -> 'a7 -> 'a8 -> 'a9 -> 'a10 -> 'a11 -> 'a12 -> ('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6, 'a7, 'a8, 'a9, 'a10, 'a11, 'a12) Slots.t13 Pointer.tval new14 : ('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6, 'a7, 'a8, 'a9, 'a10, 'a11, 'a12, 'a13) Slots.t14 t -> 'a0 -> 'a1 -> 'a2 -> 'a3 -> 'a4 -> 'a5 -> 'a6 -> 'a7 -> 'a8 -> 'a9 -> 'a10 -> 'a11 -> 'a12 -> 'a13 -> ('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6, 'a7, 'a8, 'a9, 'a10, 'a11, 'a12, 'a13) Slots.t14 Pointer.tval get_tuple : ('tuple, 'a) Slots.t t -> ('tuple, 'a) Slots.t Pointer.t -> 'tupleget_tuple t pointerallocates an OCaml tuple isomorphic to the poolt's tuple pointed to bypointer. The tuple gets copied, but its slots do not.
val get : ('a, 'variant) Slots.t t -> ('a, 'variant) Slots.t Pointer.t -> ('variant, 'slot) Slot.t -> 'slotget t pointer slotgetsslotof the tuple pointed to bypointerin poolt.set t pointer slot asets toatheslotof the tuple pointed to bypointerin poolt.In
getandset, it is an error to refer to a pointer that has beenfreed. It is also an error to use a pointer with any pool other than the one the pointer wasnew'd from orgrown to. These errors will lead to undefined behavior, but will not segfault.unsafe_getis comparable in speed togetfor immediate values, and 5%-10% faster for pointers.unsafe_getandunsafe_setskip bounds checking, and can thus segfault.
val unsafe_get : ('a, 'variant) Slots.t t -> ('a, 'variant) Slots.t Pointer.t -> ('variant, 'slot) Slot.t -> 'slotval set : ('a, 'variant) Slots.t t -> ('a, 'variant) Slots.t Pointer.t -> ('variant, 'slot) Slot.t -> 'slot -> unitval unsafe_set : ('a, 'variant) Slots.t t -> ('a, 'variant) Slots.t Pointer.t -> ('variant, 'slot) Slot.t -> 'slot -> unit
module Unsafe : sig ... endAn
Unsafepool is like an ordinary pool, except that thecreatefunction does not require an initial element. The pool stores a dummy value for each slot. Such a pool is only safe if one never accesses a slot from afreed tuple.
module Debug : functor (Tuple_pool : S) -> sig ... endDebugbuilds a pool in which every function can runinvarianton its pool argument(s) and/or print a debug message to stderr, as determined by!check_invariantand!show_messages, which are initially bothtrue.
module Error_check : functor (Tuple_pool : S) -> SError_checkbuilds a pool that has additional error checking for pointers, in particular to detect using afreed pointer or multiplyfreeing a pointer.