Debug
builds a pool in which every function can run invariant
on its pool
argument(s) and/or print a debug message to stderr, as determined by
!check_invariant
and !show_messages
, which are initially both true
.
The performance of the pool resulting from Debug
is much worse than that of the
input Pool
, even with all the controls set to false
.
include S with type 'a Pointer.t = 'a Pool.Pointer.t with type Pointer.Id.t = Pool.Pointer.Id.t with type 'a t = 'a Pool.t
module Slots : Tuple_type.Slots
module Slot : Tuple_type.Slot
module Pointer : sig ... end with type 'a t = 'a Pool.Pointer.t and type Id.t = Pool.Pointer.Id.t
A pool. 'slots
will look like ('a1, ..., 'an) Slots.tn
, and the pool holds
tuples of type 'a1 * ... * 'an
.
include sig ... end
val sexp_of_t : ('slots ‑> Base.Sexp.t) ‑> 'slots t ‑> Base.Sexp.t
include Core_kernel__.Import.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 ‑> Core_kernel__.Import.bool
pointer_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.t
id_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.t
pointer_of_id_exn t id
returns the pointer corresponding to id
. It fails if the
tuple corresponding to id
was already free
d.
val create : ('tuple, _) Slots.t as slots ‑> capacity:Core_kernel__.Import.int ‑> dummy:'tuple ‑> 'slots t
create 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.int
max_capacity
returns the maximum capacity allowed when creating a pool.
val capacity : _ t ‑> Core_kernel__.Import.int
capacity
returns the maximum number of tuples that the pool can hold.
val length : _ t ‑> Core_kernel__.Import.int
length
returns the number of tuples currently in the pool.
0 <= length t <= capacity t
val grow : ?capacity:Core_kernel__.Import.int ‑> 'a t ‑> 'a t
grow 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.bool
is_full t
returns true
if no more tuples can be allocated in t
.
val free : 'slots t ‑> 'slots Pointer.t ‑> Core_kernel__.Import.unit
free t pointer
frees the tuple pointed to by pointer
from t
.
val unsafe_free : 'slots t ‑> 'slots Pointer.t ‑> Core_kernel__.Import.unit
unsafe_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 free
d. It
is also an error to use a pointer with any pool other than the one the pointer was
new
'd from or grow
n 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.unit
val unsafe_set : (_, 'variant) Slots.t as slots t ‑> 'slots Pointer.t ‑> ('variant, 'slot) Slot.t ‑> 'slot ‑> Core_kernel__.Import.unit
val check_invariant : Core_kernel__.Import.bool Core_kernel__.Import.ref
val show_messages : Core_kernel__.Import.bool Core_kernel__.Import.ref