Skip to main content

atomr_core/util/
bounded_queue.rs

1//! A simple bounded FIFO queue used by bounded mailboxes.
2
3use std::collections::VecDeque;
4
5#[derive(Debug)]
6pub struct BoundedQueue<T> {
7    cap: usize,
8    inner: VecDeque<T>,
9}
10
11impl<T> BoundedQueue<T> {
12    pub fn new(cap: usize) -> Self {
13        Self { cap, inner: VecDeque::with_capacity(cap) }
14    }
15
16    pub fn capacity(&self) -> usize {
17        self.cap
18    }
19
20    pub fn len(&self) -> usize {
21        self.inner.len()
22    }
23
24    pub fn is_empty(&self) -> bool {
25        self.inner.is_empty()
26    }
27
28    pub fn is_full(&self) -> bool {
29        self.inner.len() >= self.cap
30    }
31
32    pub fn push(&mut self, item: T) -> Result<(), T> {
33        if self.is_full() {
34            Err(item)
35        } else {
36            self.inner.push_back(item);
37            Ok(())
38        }
39    }
40
41    pub fn pop(&mut self) -> Option<T> {
42        self.inner.pop_front()
43    }
44
45    /// Remove and return the most-recently-enqueued element, if any.
46    /// Used by [`OverflowStrategy::DropTail`].
47    pub fn pop_back(&mut self) -> Option<T> {
48        self.inner.pop_back()
49    }
50
51    pub fn push_front(&mut self, item: T) -> Result<(), T> {
52        if self.is_full() {
53            Err(item)
54        } else {
55            self.inner.push_front(item);
56            Ok(())
57        }
58    }
59}
60
61#[cfg(test)]
62mod tests {
63    use super::*;
64
65    #[test]
66    fn fifo_order() {
67        let mut q = BoundedQueue::new(3);
68        q.push(1).unwrap();
69        q.push(2).unwrap();
70        q.push(3).unwrap();
71        assert!(q.is_full());
72        assert!(q.push(4).is_err());
73        assert_eq!(q.pop(), Some(1));
74        assert_eq!(q.pop(), Some(2));
75        assert_eq!(q.pop(), Some(3));
76        assert!(q.is_empty());
77    }
78}