use core::time::Duration;
use std::{collections::VecDeque, time::Instant};
pub(crate) struct ResetCounter {
timestamps: VecDeque<Instant>,
max: usize,
window: Duration,
}
impl ResetCounter {
pub(crate) fn new(max: usize, window: Duration) -> Self {
Self {
timestamps: VecDeque::new(),
max,
window,
}
}
#[cold]
#[inline(never)]
pub(crate) fn tick(&mut self) -> bool {
let now = Instant::now();
self.drain_expired(now);
self.timestamps.push_back(now);
self.timestamps.len() > self.max
}
fn drain_expired(&mut self, now: Instant) {
while let Some(&front) = self.timestamps.front() {
if now.saturating_duration_since(front) > self.window {
self.timestamps.pop_front();
} else {
break;
}
}
}
}