Module type Pool_intf.S

module type S = sig .. end
S is the module type for a pool.

module Slots: Tuple_type.Slots 
module Slot: Tuple_type.Slot 
module Pointer: sig .. end
type 'slots t 
A pool. 'slots will look like ('a1, ..., 'an) Slots.tn, and the pool holds tuples of type 'a1 * ... * 'an.
include Invariant.S1
val pointer_is_valid : 'slots t -> 'slots Pointer.t -> 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 freed.

pointer_of_id_exn_is_supported says whether the implementation supports pointer_of_id_exn; if not, it will always raise. We can not use the usual idiom of making pointer_of_id_exn be an Or_error.t due to problems with the value restriction.

val pointer_of_id_exn_is_supported : bool
val create : ('tuple, 'a) Slots.t ->
capacity:int -> dummy:'tuple -> ('tuple, 'a) Slots.t 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.
val capacity : 'a t -> int
capacity returns the maximum number of tuples that the pool can hold.
val length : 'a t -> int
length returns the number of tuples currently in the pool.

        0 <= length t <= capacity t
      

val grow : ?capacity: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 : 'a t -> bool
is_full t returns true if no more tuples can be allocated in t.
val free : 'slots t -> 'slots Pointer.t -> unit
free t pointer frees the tuple pointed to by pointer from t.
val new1 : 'a0 Slots.t1 t -> 'a0 -> 'a0 Slots.t1 Pointer.t
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.
val new2 : ('a0, 'a1) Slots.t2 t ->
'a0 -> 'a1 -> ('a0, 'a1) Slots.t2 Pointer.t
val new3 : ('a0, 'a1, 'a2) Slots.t3 t ->
'a0 -> 'a1 -> 'a2 -> ('a0, 'a1, 'a2) Slots.t3 Pointer.t
val new4 : ('a0, 'a1, 'a2, 'a3) Slots.t4 t ->
'a0 ->
'a1 -> 'a2 -> 'a3 -> ('a0, 'a1, 'a2, 'a3) Slots.t4 Pointer.t
val new5 : ('a0, 'a1, 'a2, 'a3, 'a4) Slots.t5 t ->
'a0 ->
'a1 ->
'a2 -> 'a3 -> 'a4 -> ('a0, 'a1, 'a2, 'a3, 'a4) Slots.t5 Pointer.t
val 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.t
val 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.t
val 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.t
val 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.t
val get_tuple : ('tuple, 'a) Slots.t t ->
('tuple, 'a) Slots.t Pointer.t -> 'tuple
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.
val get : ('a, 'variant) Slots.t t ->
('a, 'variant) Slots.t Pointer.t ->
('variant, 'slot) Slot.t -> 'slot
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 unsafe_get : ('a, 'variant) Slots.t t ->
('a, 'variant) Slots.t Pointer.t ->
('variant, 'slot) Slot.t -> 'slot
val set : ('a, 'variant) Slots.t t ->
('a, 'variant) Slots.t Pointer.t ->
('variant, 'slot) Slot.t -> 'slot -> unit
val unsafe_set : ('a, 'variant) Slots.t t ->
('a, 'variant) Slots.t Pointer.t ->
('variant, 'slot) Slot.t -> 'slot -> unit
val sexp_of_t : ('slots -> Sexplib.Sexp.t) -> 'slots t -> Sexplib.Sexp.t

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.

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.

pointer_of_id_exn t id returns the pointer corresponding to id. It fails if the tuple corresponding to id was already freed.

pointer_of_id_exn_is_supported says whether the implementation supports pointer_of_id_exn; if not, it will always raise. We can not use the usual idiom of making pointer_of_id_exn be an Or_error.t due to problems with the value restriction.

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 returns the maximum number of tuples that the pool can hold.

length returns the number of tuples currently in the pool.

        0 <= length t <= capacity 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.

default is 2 * capacity t

is_full t returns true if no more tuples can be allocated in t.

free t pointer frees the tuple pointed to by pointer from t.

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.