use std::collections::VecDeque;
use std::time::Duration;
const WINDOW: usize = 3;
const THRESHOLD: Duration = Duration::from_millis(50);
#[derive(Debug, Default)]
pub struct RuleLatencyTracker {
pub recent_durations: VecDeque<Duration>,
pub reclassified: bool,
}
impl RuleLatencyTracker {
pub fn record(&mut self, duration: Duration) -> bool {
if self.reclassified {
return false;
}
if self.recent_durations.len() >= WINDOW {
self.recent_durations.pop_front();
}
self.recent_durations.push_back(duration);
if self.recent_durations.len() == WINDOW
&& self.recent_durations.iter().all(|d| *d > THRESHOLD)
{
self.reclassified = true;
return true;
}
false
}
#[inline]
pub fn is_reclassified(&self) -> bool {
self.reclassified
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn reclassifies_after_three_slow_evaluations() {
let mut t = RuleLatencyTracker::default();
let slow = Duration::from_millis(60);
assert!(!t.record(slow));
assert!(!t.record(slow));
assert!(t.record(slow)); assert!(t.is_reclassified());
assert!(!t.record(slow)); }
#[test]
fn does_not_reclassify_on_mixed_durations() {
let mut t = RuleLatencyTracker::default();
let fast = Duration::from_millis(10);
let slow = Duration::from_millis(60);
t.record(slow);
t.record(fast); t.record(slow);
assert!(!t.is_reclassified());
}
}