-
Notifications
You must be signed in to change notification settings - Fork 42
/
Copy pathgrowArray.ml
74 lines (57 loc) · 1.77 KB
/
growArray.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
(** Growable Arrays *)
module LA = Longarray
type 'a fill =
Elem of 'a
| Susp of (int -> 'a)
type 'a t = {
gaFill: 'a fill;
(** Stuff to use to fill in the array as it grows *)
mutable gaMaxInitIndex: int;
(** Maximum index that was written to. -1 if no writes have
* been made. *)
mutable gaData: 'a LA.t;
}
let growTheArray (ga: 'a t) (len: int)
(toidx: int) (why: string) : unit =
if toidx >= len then begin
(* Grow the array by 50% *)
let newlen = toidx + 1 + len / 2 in
let data' = begin match ga.gaFill with
Elem x ->
let data'' = LA.create newlen x in
LA.blit ga.gaData 0 data'' 0 len;
data''
| Susp f -> LA.init newlen
(fun i -> if i < len then LA.get ga.gaData i else f i)
end
in
ga.gaData <- data'
end
let max_init_index (ga: 'a t) : int =
ga.gaMaxInitIndex
let num_alloc_index (ga: 'a t) : int =
LA.length ga.gaData
let reset_max_init_index (ga: 'a t) : unit =
ga.gaMaxInitIndex <- -1
let getg (ga: 'a t) (r: int) : 'a =
let len = LA.length ga.gaData in
if r >= len then
growTheArray ga len r "getg";
LA.get ga.gaData r
let setg (ga: 'a t) (r: int) (what: 'a) : unit =
let len = LA.length ga.gaData in
if r >= len then
growTheArray ga len r "setg";
if r > max_init_index ga then ga.gaMaxInitIndex <- r;
LA.set ga.gaData r what
let get (ga: 'a t) (r: int) : 'a = LA.get ga.gaData r
let set (ga: 'a t) (r: int) (what: 'a) : unit =
if r > max_init_index ga then ga.gaMaxInitIndex <- r;
LA.set ga.gaData r what
let make (initsz: int) (fill: 'a fill) : 'a t =
{ gaFill = fill;
gaMaxInitIndex = -1;
gaData = begin match fill with
Elem x -> LA.create initsz x
| Susp f -> LA.init initsz f
end; }