1use std::collections::VecDeque;
2
3#[derive(Clone, Debug)]
19#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
20pub struct History<T> {
21 min_len: usize,
24
25 max_len: usize,
27
28 max_age: f32,
30
31 total_count: u64,
33
34 values: VecDeque<(f64, T)>,
37}
38
39impl<T> History<T>
40where
41 T: Copy,
42{
43 pub fn new(length_range: std::ops::Range<usize>, max_age: f32) -> Self {
56 Self {
57 min_len: length_range.start,
58 max_len: length_range.end,
59 max_age,
60 total_count: 0,
61 values: Default::default(),
62 }
63 }
64
65 #[inline]
66 pub fn max_len(&self) -> usize {
67 self.max_len
68 }
69
70 #[inline]
71 pub fn max_age(&self) -> f32 {
72 self.max_age
73 }
74
75 #[inline]
76 pub fn is_empty(&self) -> bool {
77 self.values.is_empty()
78 }
79
80 #[inline]
82 pub fn len(&self) -> usize {
83 self.values.len()
84 }
85
86 #[inline]
89 pub fn total_count(&self) -> u64 {
90 self.total_count
91 }
92
93 pub fn latest(&self) -> Option<T> {
94 self.values.back().map(|(_, value)| *value)
95 }
96
97 pub fn latest_mut(&mut self) -> Option<&mut T> {
98 self.values.back_mut().map(|(_, value)| value)
99 }
100
101 pub fn duration(&self) -> f32 {
103 if let (Some(front), Some(back)) = (self.values.front(), self.values.back()) {
104 (back.0 - front.0) as f32
105 } else {
106 0.0
107 }
108 }
109
110 pub fn iter(&self) -> impl ExactSizeIterator<Item = (f64, T)> + '_ {
114 self.values.iter().map(|(time, value)| (*time, *value))
115 }
116
117 pub fn values(&self) -> impl ExactSizeIterator<Item = T> + '_ {
118 self.values.iter().map(|(_time, value)| *value)
119 }
120
121 #[inline]
122 pub fn clear(&mut self) {
123 self.values.clear();
124 }
125
126 pub fn add(&mut self, now: f64, value: T) {
128 if let Some((last_time, _)) = self.values.back() {
129 debug_assert!(*last_time <= now, "Time shouldn't move backwards");
130 }
131 self.total_count += 1;
132 self.values.push_back((now, value));
133 self.flush(now);
134 }
135
136 pub fn mean_time_interval(&self) -> Option<f32> {
138 if let (Some(first), Some(last)) = (self.values.front(), self.values.back()) {
139 let n = self.len();
140 if n >= 2 {
141 Some((last.0 - first.0) as f32 / ((n - 1) as f32))
142 } else {
143 None
144 }
145 } else {
146 None
147 }
148 }
149
150 pub fn rate(&self) -> Option<f32> {
152 self.mean_time_interval().map(|time| 1.0 / time)
153 }
154
155 pub fn flush(&mut self, now: f64) {
157 while self.values.len() > self.max_len {
158 self.values.pop_front();
159 }
160 while self.values.len() > self.min_len {
161 if let Some((front_time, _)) = self.values.front() {
162 if *front_time < now - (self.max_age as f64) {
163 self.values.pop_front();
164 } else {
165 break;
166 }
167 } else {
168 break;
169 }
170 }
171 }
172}
173
174impl<T> History<T>
175where
176 T: Copy,
177 T: std::iter::Sum,
178 T: std::ops::Div<f32, Output = T>,
179{
180 #[inline]
181 pub fn sum(&self) -> T {
182 self.values().sum()
183 }
184
185 pub fn average(&self) -> Option<T> {
186 let num = self.len();
187 if num > 0 {
188 Some(self.sum() / (num as f32))
189 } else {
190 None
191 }
192 }
193}
194
195impl<T> History<T>
196where
197 T: Copy,
198 T: std::iter::Sum,
199 T: std::ops::Div<f32, Output = T>,
200 T: std::ops::Mul<f32, Output = T>,
201{
202 pub fn bandwidth(&self) -> Option<T> {
206 Some(self.average()? * self.rate()?)
207 }
208}
209
210impl<T, Vel> History<T>
211where
212 T: Copy,
213 T: std::ops::Sub<Output = Vel>,
214 Vel: std::ops::Div<f32, Output = Vel>,
215{
216 pub fn velocity(&self) -> Option<Vel> {
219 if let (Some(first), Some(last)) = (self.values.front(), self.values.back()) {
220 let dt = (last.0 - first.0) as f32;
221 if dt > 0.0 {
222 Some((last.1 - first.1) / dt)
223 } else {
224 None
225 }
226 } else {
227 None
228 }
229 }
230}