use std::{
collections::VecDeque,
time::{Duration, Instant},
};
pub const ENFORCED_SIZE_TIME: u64 = 1;
pub struct ReceivedPacketCache {
target: usize,
time_window: u64,
within_enforced_time: usize,
inner: VecDeque<Instant>,
}
impl ReceivedPacketCache {
pub fn new(target: usize, time_window: u64) -> Self {
Self {
target,
time_window,
within_enforced_time: 0,
inner: VecDeque::with_capacity(target * time_window as usize),
}
}
pub fn reset(&mut self) {
while let Some(received_at) = self.inner.pop_front() {
if received_at
> Instant::now()
.checked_sub(Duration::from_secs(self.time_window))
.unwrap()
{
self.inner.push_front(received_at);
break;
}
}
let mut count = 0;
for received_at in self.inner.iter().rev() {
if *received_at
> Instant::now()
.checked_sub(Duration::from_secs(ENFORCED_SIZE_TIME))
.unwrap()
{
count += 1;
} else {
break;
}
}
self.within_enforced_time = count;
}
pub fn cache_insert(&mut self) -> bool {
self.reset();
self.internal_insert()
}
fn internal_insert(&mut self) -> bool {
if self.within_enforced_time >= self.target {
false
} else {
self.inner.push_back(Instant::now());
self.within_enforced_time += 1;
true
}
}
}
impl std::ops::Deref for ReceivedPacketCache {
type Target = VecDeque<Instant>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl std::ops::DerefMut for ReceivedPacketCache {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}