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 Obj_array
backing the pool: free, create, grow.
include S with type 'a Pointer.t = private Core_kernel__.Import.intmodule Slots : Core_kernel.Tuple_type.Slotsmodule Slot : Core_kernel.Tuple_type.Slotmodule Pointer : sig ... end with type 'a t = private Core_kernel__.Import.inttype 'slots tA pool. 'slots will look like ('a1, ..., 'an) Slots.tn, and the pool holds
tuples of type 'a1 * ... * 'an.
include sig ... endval sexp_of_t : ('slots ‑> Base.Sexp.t) ‑> 'slots t ‑> Base.Sexp.tinclude Core_kernel__.Import.Invariant.S1 with type a t := a tval invariant : 'a Base__.Invariant_intf.inv ‑> 'a t Base__.Invariant_intf.invval pointer_is_valid : 'slots t ‑> 'slots Pointer.t ‑> Core_kernel__.Import.boolpointer_is_valid t pointer returns true iff pointer points to a live tuple in
t, i.e. pointer is not null, not free, and is in the range of t.
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 pointer returns an id that is unique for the lifetime of
pointer's tuple. When the tuple is freed, the id is no longer valid, and
pointer_of_id_exn will 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 id returns the pointer corresponding to id. It fails if the
tuple corresponding to id was already freed.
val create : ('tuple, _) Slots.t as slots ‑> capacity:Core_kernel__.Import.int ‑> dummy:'tuple ‑> 'slots tcreate slots ~capacity ~dummy creates an empty pool that can hold up to capacity
N-tuples. The slots of dummy are stored in free tuples. create raises if
capacity < 0 || capacity > max_capacity ~slots_per_tuple.
val max_capacity : slots_per_tuple:Core_kernel__.Import.int ‑> Core_kernel__.Import.intmax_capacity returns the maximum capacity allowed when creating a pool.
val capacity : _ t ‑> Core_kernel__.Import.intcapacity returns the maximum number of tuples that the pool can hold.
val length : _ t ‑> Core_kernel__.Import.intlength returns the number of tuples currently in the pool.
0 <= length t <= capacity tval grow : ?capacity:Core_kernel__.Import.int ‑> 'a t ‑> 'a tgrow t ~capacity returns a new pool t' with the supplied capacity. The new pool
is to be used as a replacement for t. All live tuples in t are now live in
t', and valid pointers to tuples in t are now valid pointers to the identical
tuple in t'. It is an error to use t after calling grow t.
grow raises if the supplied capacity isn't larger than capacity t.
val is_full : _ t ‑> Core_kernel__.Import.boolis_full t returns true if no more tuples can be allocated in t.
val free : 'slots t ‑> 'slots Pointer.t ‑> Core_kernel__.Import.unitfree t pointer frees the tuple pointed to by pointer from t.
val unsafe_free : 'slots t ‑> 'slots Pointer.t ‑> Core_kernel__.Import.unitunsafe_free t pointer frees the tuple pointed to by pointer without checking
pointer_is_valid
new<N> t a0 ... a<N-1> returns a new tuple from the pool, with the tuple's
slots initialized to a0 ... a<N-1>. new raises if is_full t.
get_tuple t pointer allocates an OCaml tuple isomorphic to the pool t's tuple
pointed to by pointer. The tuple gets copied, but its slots do not.
get t pointer slot gets slot of the tuple pointed to by pointer in
pool t.
set t pointer slot a sets to a the slot of the tuple pointed to by pointer
in pool t.
In get and set, it is an error to refer to a pointer that has been freed. It
is also an error to use a pointer with any pool other than the one the pointer was
new'd from or grown to. These errors will lead to undefined behavior, but will
not segfault.
unsafe_get is comparable in speed to get for immediate values, and 5%-10% faster
for pointers.
unsafe_get and unsafe_set skip bounds checking, and can thus segfault.
val set : (_, 'variant) Slots.t as slots t ‑> 'slots Pointer.t ‑> ('variant, 'slot) Slot.t ‑> 'slot ‑> Core_kernel__.Import.unitval unsafe_set : (_, 'variant) Slots.t as slots t ‑> 'slots Pointer.t ‑> ('variant, 'slot) Slot.t ‑> 'slot ‑> Core_kernel__.Import.unitval create : (_, _) Slots.t as slots ‑> capacity:Core_kernel__.Import.int ‑> 'slots tcreate slots ~capacity creates an empty pool that can hold up to capacity
N-tuples. The elements of a free tuple may contain stale and/or invalid values
for their types, and as such any access to a free tuple from this pool is
unsafe.