Library
Module
Module type
Parameter
Class
Class type
A varray is a variable sized array, also known as a resizable or dynamic array.
Just like an array, random access / update is O(1). But you can also grow the varray by appending or prepending an element in constant time. Insertion and deletion at a specific index cost O(k√N) for any constant k ≥ 1
of your choosing.
For convenience, the recommended complexity tradeoff between time and memory is provided below with the constant parameter k = 2
. You will find the internal building blocks at the end of this documentation to create a custom Varray with different asymptotics.
push_back t x
adds a new element x
at the end of the varray t
. O(k) amortized.
pop_back t
removes and returns the rightmost element of the varray t
. O(k) amortized.
push_front t x
inserts a new element x
at position 0
, on the left side of the varray t
. Every previous element of t
is shifted one to the right. O(k) amortized.
pop_front t
removes and returns the leftmost element at position 0
of the varray t
. Every element of t
is shifted one to the right. O(k) amortized.
insert_at t i x
inserts the element x
at position i
in the varray t
. Every element on the right of i
is shifted by one. O(k² × k√N)
insert_at t 0 x
is the same as push_front t x
insert_at t (length t) x
is the same as push_back t x
pop_at t i
removes and returns the element t.(i)
. Every element on the right of i
is shifted by one to the left. O(k² × k√N)
pop_at t 0
is the same as pop_front t
pop_at t (length t - 1)
is the same as pop_back t
val delete_at : 'a t -> int -> unit
delete_at t i
removes the element t.(i)
. Every element on the right of i
is shifted by one to the left. O(k² × k√N)
The previous operations all fail when the varray is being traversed:
val protect : 'a t -> (unit -> 'b) -> 'b
protect t fn
marks t
as protected during the execution of fn ()
. All operations that would update the length of t
by pushing or poping elements will raise a Failure
indicating that the traversal is unsafe.
get t i
returns the i
th element of the varray. Indexing starts from 0
upto length t - 1
. O(k)
val length : 'a t -> int
length t
returns the number of elements stored in t
. O(1)
make n x
returns a new varray of length n
, where all the elements are initialized to the value x
.
init n f
returns a new array of length n
, where the element at position i
is initialized to f i
.
val empty : unit -> 'a t
empty ()
is a new varray of length 0
.
val is_empty : 'a t -> bool
is_empty t
returns true when the varray t
has length 0
.
append a b
returns a new varray by concatening the elements of a
with those of b
.
concat ts
returns a new varray whose elements are in the same order as the values from the list of varrays ts
.
sub t i n
returns a new varray of length n
, containing the elements from the range i, i+n-1
of the varray t
.
fill t pos len x
modifies the varray t
in place, by setting the value x
in the range pos, pos + len - 1
.
blit src src_pos dst dst_pos len
updates the varray dst
in place, by copying the range src_pos, src_pos + len - 1
of values from src
into the destination range dst_pos, dst_pos + len - 1
of dst
.
iter f t
calls the function f
on all elements of t
, from left to right.
iteri f t
calls f i t.(i)
on all the indexes i
of t
, from left to right.
map f t
returns a new varray, whose elements are f x
for each x
from the varray t
.
mapi f t
returns a new varray, whose elements are f i t.(i)
for each index i
of the varray t
.
fold_left f z t
computes f (... (f (f z t.(0)) t.(1)) ...) t.(length t - 1)
.
fold_right f t z
computes f t.(0) (f t.(1) (... (f z t.(length t - 1))))
.
fold_left_map
is a combination of fold_left
and map
, that threads an accumulator.
iter2 f xs ys
calls f xs.(i) ys.(i)
for each index i
from left to right.
map2 f xs ys
returns a new varray whose i
th element is f xs.(i) ys.(i)
.
for_all f t
holds when f
is satisfied by all the elements of t
.
for_all2 f xs ys
holds when f xs.(i) ys.(i)
is satisfied by all indexes i
.
exists f t
holds when f
is satisfied by one of the elements of t
.
exists2 f xs ys
holds when an index i
exists such that f xs.(i) ys.(i)
is satisfied.
find_opt f t
returns the leftmost element of t
that satisfies f
.
find_map f t
returns the first result of f
of the form Some v
.
mem x t
is true when x
is equal ( = )
to an element of the varray t
.
Same as mem
, but memq x t
uses physical equality ( == )
for comparison.
sort cmp t
updates t
inplace by sorting the elements in increasing order according to cmp
.
Same as sort
, but equal elements are kept in the same relative order.
type 'a array = 'a Array.t
The array type used behind the scene as a backend by the varray.
of_array arr
returns a new varray containing all the elements of the array arr
.
to_array t
returns a new array containing all the elements of the varray t
.
of_list xs
returns a new varray containing all the elements of the list xs
.
The signature of the internal operations, required by the Root
functor below.
module type S = sig ... end
The signature of a varray.
The family of varrays is defined by calling the Root
functor as many times as required:
Module | get , set
push , pop |
insert_at delete_at |
Memory overhead |
---|---|---|---|
Circular |
O(1) | O(N) | O(N) |
Root (Circular) |
O(1) | O(2√N) | O(2√N) |
Root (Root (Circular)) |
O(1) | O(3√N) | O(N2/3) |
Rootk-1 (Circular) |
O(k) | O(k2 × k√N) | O(Nk-1 / k) |
The first step is to choose a backend Array
that will be used to store the elements:
module type ARRAY = sig ... end
The array will be used partially, with some elements in an undefined state. It is guaranteed that all operations always use valid indexes.
Some good candidates from the standard library are Array
for polymorphic values, BigArray.Array1
for numbers, Bytes
for characters, or Weak
for weak pointers.
Make (Array)
returns a circular varray using Array
as its backend. The resulting varray has parameter k = 1
, meaning that push
and pop
at both ends is O(1) but random insertion and deletions are O(N).
Circular
is a predefined circular varray using a polymorphic Stdlib.Array
.
Root (Varray)
nests an existing Varray
to improve the performances of random insertion and deletion. However, it does so at the price that random access and insertion and deletion at the ends will be a constant time slower!