event_scanner/block_range_scanner/
ring_buffer.rs

1use std::collections::VecDeque;
2
3#[derive(Copy, Clone, Debug)]
4pub enum RingBufferCapacity {
5    Limited(usize),
6    Infinite,
7}
8
9macro_rules! impl_from_unsigned {
10    ($target:ty; $($source:ty),+ $(,)?) => {
11        $(
12            impl From<$source> for $target {
13                fn from(value: $source) -> Self {
14                    RingBufferCapacity::Limited(value as usize)
15                }
16            }
17        )+
18    };
19}
20
21impl_from_unsigned!(RingBufferCapacity; u8, u16, u32, usize);
22
23#[derive(Clone)]
24pub(crate) struct RingBuffer<T> {
25    inner: VecDeque<T>,
26    capacity: RingBufferCapacity,
27}
28
29impl<T> RingBuffer<T> {
30    /// Creates an empty [`RingBuffer`] with a specific capacity.
31    pub fn new(capacity: RingBufferCapacity) -> Self {
32        if let RingBufferCapacity::Limited(limit) = capacity {
33            Self { inner: VecDeque::with_capacity(limit), capacity }
34        } else {
35            Self { inner: VecDeque::new(), capacity }
36        }
37    }
38
39    /// Adds a new element to the buffer.
40    ///
41    /// If limited capacity and the buffer is full, the oldest element is removed to make space.
42    pub fn push(&mut self, item: T) {
43        match self.capacity {
44            RingBufferCapacity::Infinite => {
45                self.inner.push_back(item); // Add the new element
46            }
47            RingBufferCapacity::Limited(0) => {
48                // Do nothing, reorg handling disabled
49            }
50            RingBufferCapacity::Limited(limit) => {
51                if self.inner.len() == limit {
52                    self.inner.pop_front(); // Remove the oldest element
53                }
54                self.inner.push_back(item); // Add the new element
55            }
56        }
57    }
58
59    pub fn pop_back(&mut self) -> Option<T> {
60        self.inner.pop_back()
61    }
62
63    pub fn back(&self) -> Option<&T> {
64        self.inner.back()
65    }
66
67    pub fn clear(&mut self) {
68        self.inner.clear();
69    }
70}
71
72#[cfg(test)]
73mod tests {
74    use super::*;
75
76    #[test]
77    fn zero_capacity_should_ignore_elements() {
78        let mut buf = RingBuffer::<u32>::new(RingBufferCapacity::Limited(0));
79        buf.push(1);
80        assert!(buf.inner.is_empty());
81    }
82}