Tweaks

2 files changed,27insertions(+),16deletions(-) M lib/vector.ml M lib/vector.mli

M lib/vector.ml => lib/vector.ml +9 -16

@@ 18,6 18,7 @@ let inner_mask = branch_factor - 1let outer_mask = lnot inner_mask type 'a node = { (* Note: This array is always [branch_factor]-sized. *) array : 'a node_item array; } [@@unboxed] and 'a node_item =@@ 43,8 44,13 @@ type 'a t = {(* The "tail" is an optimization to the vector that allows true-constant time access to the end of the vector, in recognition of the fact that vectors are often pushed and popped at the end. Typed as 'a node_item to match node type, but is logically 'a option array. i.e., this should never hold Inner, only Leaf or Empty *) i.e., this should never hold Inner, only Leaf or Empty Note: This array will grow and shrink as the vector is updated, unlike the array inside 'a node. *) tail : 'a node_item array; }@@ 67,7 73,6 @@ let empty () : 'a t =*) Obj.magic empty_value (** Returns the length of the vector *) let length (t : 'a t) : int = t.count (** Returns the logical index represented by tail.(0) *)@@ 96,7 101,6 @@ let array_for (t : 'a t) (i : int) : 'a node_item array option =in Some (descend t.root t.height) (** Gets the element at index, or None if out of bounds *) let nth_opt (t : 'a t) (index : int) : 'a option = let last_level_index = index land inner_mask in match array_for t index with@@ 107,23 111,15 @@ let nth_opt (t : 'a t) (index : int) : 'a option =| Inner _ -> failwith "Invariant violation, not expecting Inner in last-level array") | _ -> None (** Gets the element at index, or raises Invalid_argument if out of bounds *) let nth (t : 'a t) (index : int) : 'a = match nth_opt t index with | Some value -> value | None -> invalid_arg "Index out of bounds" (** Appends an element to the vector *) let append (t : 'a t) (value : 'a) : 'a t = let old_count = length t in if old_count - (tail_offset t) < branch_factor then (* *) (* Create a new tail that is one longer. Note: Array.init is no faster than this, because it gets the zeroth element, fills the array with that, then sets all the subsequent elements. Do it manually here to avoid a closure allocation. *) (* Create a new tail that is one longer *) let old_tail_length = Array.length t.tail in let new_tail = Array.make (old_tail_length + 1) (Leaf value) in Array.blit t.tail 0 new_tail 0 old_tail_length;@@ 174,8 170,6 @@ let append (t : 'a t) (value : 'a) : 'a t =tail = [|(Leaf value)|]; } (* Returns a new vector with index i associated to a. If i is equal to the current vector size, a is appended to the vector, expanding it. If i is less than zero or greater than the current vector size, Invalid_argument is raised. *) let update (t : 'a t) (i : int) (value : 'a) : 'a t = let count = length t in if i < 0 || i > count then@@ 228,8 222,7 @@ let pop (t : 'a t) : 'a t =let of_seq (xs : 'a Seq.t) : 'a t = Seq.fold_left append (empty ()) xs (** Dead-simple Sequence implementation. TODO: optimize by holding onto the leaf so we don't have to walk down every time *) (* TODO: optimize by holding onto the leaf so we don't have to walk down every time *) let to_seq (t : 'a t) : 'a Seq.t = Seq.init t.count (fun i -> nth t i)

M lib/vector.mli => lib/vector.mli +18 -0

@@ 15,14 15,32 @@ val nth : 'a t -> int -> 'a(** Appends an element to the vector *) val append : 'a t -> 'a -> 'a t (** Returns a new vector with index i associated to a. If i is equal to the current vector size, a is appended to the vector, expanding it. If i is less than zero or greater than the current vector size, Invalid_argument is raised. *) val update : 'a t -> int -> 'a -> 'a t (** Returns a new vector with the last element removed. If the vector was empty, returns [None]. *) val pop_opt : 'a t -> 'a t option (** Returns a new vector with the last element removed. If the vector was empty, raises [Invalid_argument] *) val pop : 'a t -> 'a t (** Builds a vector from the provided sequence, which is consumed once entirely. *) val of_seq : 'a Seq.t -> 'a t (** Converts this vector to a sequence. The returned sequence can be reused. *) val to_seq : 'a t -> 'a Seq.t (** Determines of two vectors are equal according to the provided element comparator. *) val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool