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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use std::time;
use std::{fmt, iter::DoubleEndedIterator, mem, vec::Vec};
pub struct HistoryBuffer<T> {
max_size: usize,
write_index: usize,
buffer: Vec<T>,
last_data_at: time::Instant,
}
impl<T> HistoryBuffer<T> {
pub fn new(max_size: usize) -> Self {
HistoryBuffer {
max_size,
write_index: 0,
buffer: Vec::with_capacity(max_size),
last_data_at: time::Instant::now(),
}
}
pub fn is_empty(&self) -> bool {
self.buffer.len() == 0
}
pub fn is_full(&self) -> bool {
self.buffer.len() == self.max_size
}
pub fn max_len(&self) -> usize {
self.max_size
}
pub fn len(&self) -> usize {
self.buffer.len()
}
pub fn clear(&mut self) {
self.write_index = 0;
self.buffer.clear();
}
pub fn most_recent(&self) -> Option<&T> {
if self.is_empty() {
None
} else {
if self.write_index == 0 {
self.buffer.last()
} else {
Some(&self.buffer[self.write_index - 1])
}
}
}
pub fn write(&mut self, val: T) -> Option<T> {
let r = if self.is_full() {
Some(mem::replace(&mut self.buffer[self.write_index], val))
} else {
self.buffer.push(val);
None
};
self.write_index = (self.write_index.wrapping_add(1)) % self.max_size;
self.last_data_at = time::Instant::now();
r
}
pub fn duration_since_last_measurement(&self) -> Option<time::Duration> {
if !self.is_empty() {
let now = time::Instant::now();
Some(now.duration_since(self.last_data_at))
} else {
None
}
}
pub fn all_unsorted(&self) -> &[T] {
&self.buffer
}
pub fn all(&self) -> impl DoubleEndedIterator<Item = &T> {
let write_index = self.write_index;
self.buffer[write_index..]
.iter()
.chain(self.buffer[..write_index].iter())
}
}
impl<T> fmt::Debug for HistoryBuffer<T>
where
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
f.debug_list().entries(self.all()).finish()
}
}