liminal_server/tap/
ring.rs1use std::collections::VecDeque;
8
9#[derive(Debug)]
12pub struct BoundedRing<T> {
13 entries: VecDeque<T>,
14 capacity: usize,
15 dropped: u64,
16 dropped_since_take: u64,
17}
18
19impl<T> BoundedRing<T> {
20 #[must_use]
22 pub fn new(capacity: usize) -> Self {
23 let capacity = capacity.max(1);
24 Self {
25 entries: VecDeque::with_capacity(capacity),
26 capacity,
27 dropped: 0,
28 dropped_since_take: 0,
29 }
30 }
31
32 pub fn push(&mut self, entry: T) -> bool {
35 let evicted = self.entries.len() >= self.capacity;
36 if evicted {
37 self.entries.pop_front();
38 self.dropped = self.dropped.saturating_add(1);
39 self.dropped_since_take = self.dropped_since_take.saturating_add(1);
40 }
41 self.entries.push_back(entry);
42 evicted
43 }
44
45 pub fn take(&mut self) -> (std::collections::vec_deque::Drain<'_, T>, u64) {
48 let dropped = std::mem::take(&mut self.dropped_since_take);
49 (self.entries.drain(..), dropped)
50 }
51
52 #[must_use]
54 pub fn len(&self) -> usize {
55 self.entries.len()
56 }
57
58 #[must_use]
60 pub fn is_empty(&self) -> bool {
61 self.entries.is_empty()
62 }
63
64 #[must_use]
66 pub const fn capacity(&self) -> usize {
67 self.capacity
68 }
69
70 #[must_use]
72 pub const fn dropped(&self) -> u64 {
73 self.dropped
74 }
75
76 #[must_use]
78 pub const fn dropped_since_take(&self) -> u64 {
79 self.dropped_since_take
80 }
81}