package xapi-rrd

  1. Overview
  2. Docs

Source file rrd_fring.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
(*
 * Copyright (C) 2006-2009 Citrix Systems Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; version 2.1 only. with the special
 * exception on linking described in file LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *)

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
    ; 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
  ring.data.{index}

let top ring = ring.data.{ring.current}

let iter_nb ring f nb =
  if nb > ring.size then
    raise (Invalid_argument "iter_nb: nb") ;
  (* FIXME: OPTIMIZE ME with 2 Array.iter ? *)
  for i = 0 to nb - 1 do
    f (peek ring i)
  done

(* iter directly on all element without using the index *)
let iter f a =
  for i = 0 to Bigarray.Array1.dim a - 1 do
    f 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
    (* FIXME: OPTIMIZE ME with 2 Array.blit *)
    a.(i) <- peek ring i
  done ;
  a

let get ring = get_nb ring ring.size
OCaml

Innovation. Community. Security.