use std::collections::VecDeque;
#[derive(Debug)]
pub struct BoundedRing<T> {
entries: VecDeque<T>,
capacity: usize,
dropped: u64,
dropped_since_take: u64,
}
impl<T> BoundedRing<T> {
#[must_use]
pub fn new(capacity: usize) -> Self {
let capacity = capacity.max(1);
Self {
entries: VecDeque::with_capacity(capacity),
capacity,
dropped: 0,
dropped_since_take: 0,
}
}
pub fn push(&mut self, entry: T) -> bool {
let evicted = self.entries.len() >= self.capacity;
if evicted {
self.entries.pop_front();
self.dropped = self.dropped.saturating_add(1);
self.dropped_since_take = self.dropped_since_take.saturating_add(1);
}
self.entries.push_back(entry);
evicted
}
pub fn take(&mut self) -> (std::collections::vec_deque::Drain<'_, T>, u64) {
let dropped = std::mem::take(&mut self.dropped_since_take);
(self.entries.drain(..), dropped)
}
#[must_use]
pub fn len(&self) -> usize {
self.entries.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.entries.is_empty()
}
#[must_use]
pub const fn capacity(&self) -> usize {
self.capacity
}
#[must_use]
pub const fn dropped(&self) -> u64 {
self.dropped
}
#[must_use]
pub const fn dropped_since_take(&self) -> u64 {
self.dropped_since_take
}
}