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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
module BoundedFloat = Rrd_utils.BoundedFloat
type t = {
size: int;
mutable current: int;
min: float;
max: float;
data: (float, Bigarray.float32_elt, Bigarray.c_layout) Bigarray.Array1.t
}
let make size (init : float) minimum maximum =
let ring =
{ size = size
; current = size - 1
; min = minimum
; max = maximum
; data = Bigarray.Array1.create Bigarray.float32 Bigarray.c_layout size
}
in
let bound = BoundedFloat.of_float ~minimum ~maximum ~f:BoundedFloat.To_Nan init in
Bigarray.Array1.fill ring.data @@ BoundedFloat.to_float bound;
ring
let copy x =
let y = make x.size nan x.min x.max in
Bigarray.Array1.blit x.data y.data;
y.current <- x.current;
y
let length ring = ring.size
let push ring (e : float) =
ring.current <- ring.current + 1;
if ring.current = ring.size then
ring.current <- 0;
let bound = BoundedFloat.of_float ~minimum:ring.min ~maximum:ring.max ~f:BoundedFloat.To_Nan e in
Bigarray.Array1.set ring.data ring.current @@ BoundedFloat.to_float bound
let peek ring i =
if i >= ring.size then
raise (Invalid_argument "peek: index");
let index =
let offset = ring.current - i in
if offset >= 0 then offset else ring.size + offset in
Bigarray.Array1.get ring.data index
let top ring = Bigarray.Array1.get ring.data ring.current
let iter_nb ring f nb =
if nb > ring.size then
raise (Invalid_argument "iter_nb: nb");
for i = 0 to nb - 1
do
f (peek ring i)
done
let iter f a =
for i=0 to Bigarray.Array1.dim a - 1 do
f (Bigarray.Array1.get a i)
done
let raw_iter ring f =
iter f ring.data
let iter ring f = iter_nb ring f (ring.size)
let get_nb ring nb =
if nb > ring.size then
raise (Invalid_argument "get_nb: nb");
let a = Array.make nb (top ring) in
for i = 1 to nb - 1
do
a.(i) <- peek ring i
done;
a
let get ring = get_nb ring (ring.size)