package albatross

  1. Overview
  2. Docs

Source file vmm_ring.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
(* (c) 2017 Hannes Mehnert, all rights reserved *)

(* a ring buffer with N strings, dropping old ones *)

type 'a t = {
  data : (Ptime.t * 'a) array ;
  mutable write : int ;
  size : int ;
}

let create ?(size = 1024) neutral () =
  { data = Array.make size (Ptime.min, neutral) ; write = 0 ; size }

let inc t = (succ t.write) mod t.size

let write t entry =
  Array.set t.data t.write entry ;
  t.write <- inc t

let dec t n = (pred n + t.size) mod t.size

let get_valid t idx =
  let our = Array.get t.data idx in
  if Ptime.equal (fst our) Ptime.min then
    None
  else
    Some our

let read_last t ?(tst = fun _ -> true) n =
  let rec one idx count acc =
    if count = 0 then
      acc
    else match get_valid t idx with
      | None -> acc
      | Some our ->
        if tst (snd our) then
          one (dec t idx) (pred count) (our :: acc)
        else
          one (dec t idx) count acc
  in
  one (dec t t.write) n []

let read_history t ?(tst = fun _ -> true) since =
  let rec go idx acc =
    match get_valid t idx with
    | None -> acc
    | Some entry ->
      if Ptime.is_earlier (fst entry) ~than:since then
        acc
      else if tst (snd entry) then
        go (dec t idx) (entry :: acc)
      else
        go (dec t idx) acc
  in
  go (dec t t.write) []