Commit 102041b5 authored by POTTIER Francois's avatar POTTIER Francois

Added LinearizedArray.

parent 2d7512f7
type 'a t =
(* data: *) 'a array *
(* entry: *) int array
let make (a : 'a array array) : 'a t =
let n = Array.length a in
(* Build the entry array. *)
let size = ref 0 in
let entry = Array.init n (fun i ->
let s = !size in
size := s + Array.length a.(i);
s
) in
(* Build the data array. *)
let i = ref 0
and j = ref 0 in
let data = Array.init !size (fun _ ->
while !j = Array.length a.(!i) do
i := !i + 1;
j := 0;
done;
let x = a.(!i).(!j) in
j := !j + 1;
x
) in
data, entry
let length ((_, entry) : 'a t) : int =
Array.length entry
(* This auxiliary function conceptually extends the array [entry]
to the case where [i] is [n]. *)
let _entry (data, entry) i =
let n = Array.length entry in
assert (0 <= i && i <= n);
if i < n then
entry.(i)
else
Array.length data
let row_length ((_, entry) as la : 'a t) i : int =
_entry la (i + 1) - entry.(i)
let read ((data, entry) as la : 'a t) i j : 'a =
assert (0 <= j && j < row_length la i);
data.(entry.(i) + j)
let write ((data, entry) as la : 'a t) i j (v : 'a) : unit =
assert (0 <= j && j < row_length la i);
data.(entry.(i) + j) <- v
let rec read_interval data i j =
if i = j then
[]
else
data.(i) :: read_interval data (i + 1) j
let read_row ((data, entry) as la : 'a t) i : 'a list =
read_interval data entry.(i) (_entry la (i + 1))
(* An array of arrays (of possibly different lengths!) can be ``linearized'',
i.e., encoded as a data array (by concatenating all of the little arrays)
and an entry array (which contains offsets into the data array). *)
type 'a t =
(* data: *) 'a array *
(* entry: *) int array
(* [make a] turns the array of arrays [a] into a linearized array. *)
val make: 'a array array -> 'a t
(* [read la i j] reads the linearized array [la] at indices [i] and [j].
Thus, [read (make a) i j] is equivalent to [a.(i).(j)]. *)
val read: 'a t -> int -> int -> 'a
(* [write la i j v] writes the value [v] into the linearized array [la]
at indices [i] and [j]. *)
val write: 'a t -> int -> int -> 'a -> unit
(* [length la] is the number of rows of the array [la]. Thus, [length (make
a)] is equivalent to [Array.length a]. *)
val length: 'a t -> int
(* [row_length la i] is the length of the row at index [i] in the linearized
array [la]. Thus, [row_length (make a) i] is equivalent to [Array.length
a.(i)]. *)
val row_length: 'a t -> int -> int
(* [read_row la i] reads the row at index [i], producing a list. Thus,
[read_row (make a) i] is equivalent to [Array.to_list a.(i)]. *)
val read_row: 'a t -> int -> 'a list
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment