Module Tuple_pool.Unsafe
An Unsafe pool is like an ordinary pool, except that the create function 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 a freed tuple.
It makes sense to use Unsafe if one has a small constrained chunk of code where one can prove that one never accesses a freed tuple, and one needs a pool where it is difficult to construct a dummy value.
Some Unsafe functions are faster than the corresponding safe version because they do not have to maintain values with the correct represention in the Uniform_array backing the pool: free, create, grow.
include S with type 'a Pointer.t = private int
module Slots : Tuple_type.Slotsmodule Slot : Tuple_type.Slottype '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.t
include Core_kernel.Invariant.S1 with type 'a t := 'a t
val invariant : 'a Base__.Invariant_intf.inv -> 'a t Base__.Invariant_intf.inv
val 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, _) Slots.t as 'slots -> capacity:int -> dummy:'tuple -> 'slots 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 : _ t -> intcapacityreturns the maximum number of tuples that the pool can hold.
val length : _ 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 : _ 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 as 'slots t -> 'a0 -> 'slots 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 as 'slots t -> 'a0 -> 'a1 -> 'slots Pointer.tval new3 : ('a0, 'a1, 'a2) Slots.t3 as 'slots t -> 'a0 -> 'a1 -> 'a2 -> 'slots Pointer.tval new4 : ('a0, 'a1, 'a2, 'a3) Slots.t4 as 'slots t -> 'a0 -> 'a1 -> 'a2 -> 'a3 -> 'slots Pointer.tval new5 : ('a0, 'a1, 'a2, 'a3, 'a4) Slots.t5 as 'slots t -> 'a0 -> 'a1 -> 'a2 -> 'a3 -> 'a4 -> 'slots Pointer.tval new6 : ('a0, 'a1, 'a2, 'a3, 'a4, 'a5) Slots.t6 as 'slots t -> 'a0 -> 'a1 -> 'a2 -> 'a3 -> 'a4 -> 'a5 -> 'slots Pointer.tval new7 : ('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6) Slots.t7 as 'slots t -> 'a0 -> 'a1 -> 'a2 -> 'a3 -> 'a4 -> 'a5 -> 'a6 -> 'slots Pointer.tval new8 : ('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6, 'a7) Slots.t8 as 'slots t -> 'a0 -> 'a1 -> 'a2 -> 'a3 -> 'a4 -> 'a5 -> 'a6 -> 'a7 -> 'slots Pointer.tval new9 : ('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6, 'a7, 'a8) Slots.t9 as 'slots t -> 'a0 -> 'a1 -> 'a2 -> 'a3 -> 'a4 -> 'a5 -> 'a6 -> 'a7 -> 'a8 -> 'slots Pointer.tval new10 : ('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6, 'a7, 'a8, 'a9) Slots.t10 as 'slots t -> 'a0 -> 'a1 -> 'a2 -> 'a3 -> 'a4 -> 'a5 -> 'a6 -> 'a7 -> 'a8 -> 'a9 -> 'slots Pointer.tval new11 : ('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6, 'a7, 'a8, 'a9, 'a10) Slots.t11 as 'slots t -> 'a0 -> 'a1 -> 'a2 -> 'a3 -> 'a4 -> 'a5 -> 'a6 -> 'a7 -> 'a8 -> 'a9 -> 'a10 -> 'slots Pointer.tval new12 : ('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6, 'a7, 'a8, 'a9, 'a10, 'a11) Slots.t12 as 'slots t -> 'a0 -> 'a1 -> 'a2 -> 'a3 -> 'a4 -> 'a5 -> 'a6 -> 'a7 -> 'a8 -> 'a9 -> 'a10 -> 'a11 -> 'slots Pointer.tval new13 : ('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6, 'a7, 'a8, 'a9, 'a10, 'a11, 'a12) Slots.t13 as 'slots t -> 'a0 -> 'a1 -> 'a2 -> 'a3 -> 'a4 -> 'a5 -> 'a6 -> 'a7 -> 'a8 -> 'a9 -> 'a10 -> 'a11 -> 'a12 -> 'slots Pointer.tval new14 : ('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6, 'a7, 'a8, 'a9, 'a10, 'a11, 'a12, 'a13) Slots.t14 as 'slots t -> 'a0 -> 'a1 -> 'a2 -> 'a3 -> 'a4 -> 'a5 -> 'a6 -> 'a7 -> 'a8 -> 'a9 -> 'a10 -> 'a11 -> 'a12 -> 'a13 -> 'slots Pointer.tval get_tuple : ('tuple, _) Slots.t as 'slots t -> 'slots 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 : (_, 'variant) Slots.t as 'slots t -> 'slots 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 : (_, 'variant) Slots.t as 'slots t -> 'slots Pointer.t -> ('variant, 'slot) Slot.t -> 'slotval set : (_, 'variant) Slots.t as 'slots t -> 'slots Pointer.t -> ('variant, 'slot) Slot.t -> 'slot -> unitval unsafe_set : (_, 'variant) Slots.t as 'slots t -> 'slots Pointer.t -> ('variant, 'slot) Slot.t -> 'slot -> unit