Library
Module
Module type
Parameter
Class
Class type
Persistent vectors based on bitwise tries.
This module implements vectors that
n
elements with keys ranging from 0
to n-1
like array
,array
,list
or Map.t
, andlist
or Map.t
.The implementation is based on bitwise tries. Roughly speaking, vector elements are stored in the leaves of a balanced tree and the bitwise representation of an element's index defines the path to the element in the tree. The trie uses a default branching factor of 32 (you can configure something else, see Custom vectors). Thus a vector with n elements implies trie-depth log32(n). This makes lookups and modifications quasi constant time. To further speed up (series of) appends, Pvec.t
batches appended elements into groups of 32 before descending into the tree.
If you want to know more, I recommend reading hyPiRion's series of blog posts about this data-type. It was my main source during implementation. Another source was the Java-implementation of Clojure's persistent vectors.
Disclaimer
I'm solo programming for fun and research. Nobody reviewed my code. My tests should cover most parts, but bugs might still be lurking. I think my persistent vectors will be useful for others, but I recommend reviewing the code before putting any stake on it. Luckily, it's only a few lines of code. If you review the code, please consider providing feedback.
Related OCaml stuff
pvec
. It's marked «experimental. DO NOT USE (yet)».val length : 'a t -> int
length v
returns the number of elements in vector v
.
val empty : unit -> 'a t
empty ()
returns a new vector of length 0.
val init : int -> (int -> 'a) -> 'a t
init n f
returns a vector of length n
holding the elements f(0)
, f(1)
, ... .
append x v
appends x
to the end of vector v
and returns the updated vector.
set i x v
replaces the i-th element of vector v
with x
and returns the updated vector. For i = length v
, set i x v
equals append x v
.
Returns None
if index i
is out of bounds.
val get : int -> 'a t -> 'a option
get i v
reads the i-th element from vector v
.
Returns None
if index i
is out of bounds.
val peek : 'a t -> 'a option
peek v
returns the last element of vector v
or None
if v
is empty.
pop v
removes the last element of vector v
and returns the removed element together with the updated vector.
Returns None
if v
is empty.
val get_exn : int -> 'a t -> 'a
get_exn
is similar to get
but raises Not_found
instead of returning None
.
set_exn
is similar to set
but raises Invalid_argument _
instead of returning None
.
val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'a
Like List.fold_left
.
val fold_right : ('a -> 'b -> 'b) -> 'a t -> 'b -> 'b
Similar to List.fold_right
but does not allocate additional memory.
val to_list : 'a t -> 'a list
to_list v
converts vector v
to a list.
val rev_to_list : 'a t -> 'a list
rev_to_list v
converts vector v
to a list; reverse order.
val of_list : 'a list -> 'a t
of_list v
converts list l
to a vector.
val to_array : 'a t -> 'a array
to_array v
converts vector v
to an array.
val rev_to_array : 'a t -> 'a array
rev_to_array v
converts vector v
to an array; reverse order.
val of_array : 'a array -> 'a t
of_array v
converts array l
to a vector.
The default vector t
uses branching factor 32. You may create vectors with custom branching factors. After doing
module V = Pvec.Make (struct
let branching_factor_log2 = n
end)
module V
has the same interface as Pvec
but its vectors use branching factor 2n.