tether_utils/tether_topics/
sampler.rs

1use std::time::{Duration, SystemTime};
2
3use circular_buffer::CircularBuffer;
4
5const WINDOW_SIZE: usize = 64;
6
7type Sample = u128;
8pub struct Sampler {
9    buffer: CircularBuffer<WINDOW_SIZE, Sample>,
10    interval: Duration,
11    last_sample_time: SystemTime,
12}
13
14impl Sampler {
15    pub fn new(interval_ms: u64) -> Self {
16        Sampler {
17            buffer: CircularBuffer::new(),
18            last_sample_time: SystemTime::now(),
19            interval: Duration::from_millis(interval_ms),
20        }
21    }
22
23    pub fn add_sample(&mut self, absolute: u128) -> bool {
24        if let Ok(elapsed) = self.last_sample_time.elapsed() {
25            if elapsed > self.interval {
26                self.last_sample_time = SystemTime::now();
27                self.buffer.push_back(absolute);
28                true
29            } else {
30                false
31            }
32        } else {
33            false
34        }
35    }
36
37    pub fn buffer(&self) -> &CircularBuffer<WINDOW_SIZE, Sample> {
38        &self.buffer
39    }
40
41    pub fn delta_entries(&self) -> Vec<u128> {
42        let mut result = Vec::with_capacity(WINDOW_SIZE);
43        let mut previous = 0;
44        for entry in &self.buffer {
45            let delta = entry - previous;
46            previous = *entry;
47            result.push(delta);
48        }
49        result
50    }
51}