Skip to main content

nblf_queue/owned/
queue.rs

1#[cfg(all(feature = "pool", feature = "alloc"))]
2pub use pooled_queue::*;
3
4use crate::{
5    MPMCQueue,
6    core::{
7        AsPackedValue,
8        queue::QueueCore,
9        slots::{Auto, SlotType},
10    },
11    owned::buffer::BoxedBuffer,
12};
13
14/// A `MPMCQueue` over a heap-allocated array.
15///
16/// This queue only accepts items that implement `PtrLike`.
17///
18/// If you need to store larger types, consider using `PooledQueue` instead.
19///
20/// only available on feature `alloc`
21pub struct Queue<T, S = Auto>
22where
23    T: AsPackedValue,
24    S: SlotType<T>,
25{
26    inner: QueueCore<BoxedBuffer<S::Slot>>,
27}
28
29impl<T> Queue<T, Auto>
30where
31    T: AsPackedValue,
32{
33    /// Constructs a new `Queue` with capacity `size` and slot type `Auto`.
34    /// `T` must fit into the chosen slot type
35    pub fn new(size: usize) -> Self {
36        Self::with_slot::<Auto>(size)
37    }
38
39    /// Constructs a new `Queue` with capacity `size` and slot type `S`.
40    /// `T` must fit into the slot type `S`
41    pub fn with_slot<S>(size: usize) -> Queue<T, S>
42    where
43        S: SlotType<T>,
44    {
45        Queue {
46            inner: QueueCore::new_in(BoxedBuffer::new(size)),
47        }
48    }
49}
50
51impl<T, S> MPMCQueue for Queue<T, S>
52where
53    T: AsPackedValue,
54    S: SlotType<T>,
55{
56    type Item = T;
57
58    fn push(&self, item: Self::Item) -> Result<(), Self::Item> {
59        self.inner.push(item)
60    }
61
62    fn pop(&self) -> Option<Self::Item> {
63        self.inner.pop()
64    }
65
66    fn len(&self) -> usize {
67        self.inner.len()
68    }
69
70    fn capacity(&self) -> usize {
71        self.inner.capacity()
72    }
73}
74
75#[cfg(all(feature = "pool", feature = "alloc"))]
76mod pooled_queue {
77    use super::*;
78    use crate::pool::{DataStorage, IndexStorage, ItemHandle, Pooled};
79
80    /// A pooled `MPMCQueue`.
81    ///
82    /// Unlike `Queue`, this queue may store any type, at the cost of higher runtime and higher memory.
83    ///
84    /// Only available on feature `alloc` + `pool`
85    #[allow(private_bounds)]
86    pub struct PooledQueue<T, S = Auto>
87    where
88        S: SlotType<ItemHandle<T>>,
89    {
90        #[allow(clippy::type_complexity)]
91        inner: Pooled<T, Queue<ItemHandle<T>, S>, BoxedBuffer<DataStorage<T>>, Queue<IndexStorage>>,
92    }
93
94    #[allow(private_bounds)]
95    impl<T> PooledQueue<T, Auto> {
96        /// Constructs a new `PooledQueue` with capacity `size` and slot type `Auto`
97        pub fn new(size: usize) -> Self {
98            Self::with_slot::<Auto>(size)
99        }
100
101        /// Constructs a new `PooledQueue` with capacity `size` and slot type `S`
102        pub fn with_slot<S>(size: usize) -> PooledQueue<T, S>
103        where
104            S: SlotType<ItemHandle<T>>,
105        {
106            PooledQueue {
107                inner: Pooled::new_from(
108                    Queue::with_slot(size),
109                    BoxedBuffer::new(size),
110                    Queue::with_slot(size),
111                ),
112            }
113        }
114
115        // TODO maybe export these publicly?
116
117        #[cfg(all(test, not(loom), not(shuttle)))]
118        #[allow(unused)]
119        /// Constructs a new `PooledQueue` with capacity `size`, arena size `arena_size` and slot type `Auto`
120        pub(crate) fn new_with_arena_size(size: usize, arena_size: usize) -> Self {
121            Self::with_slot_and_arena_size::<Auto>(size, arena_size)
122        }
123
124        #[cfg(all(test, not(loom), not(shuttle)))]
125        #[allow(unused)]
126        /// Constructs a new `PooledQueue` with capacity `size`, arena size `arena_size` and slot type `S`
127        pub(crate) fn with_slot_and_arena_size<S>(
128            size: usize,
129            arena_size: usize,
130        ) -> PooledQueue<T, S>
131        where
132            S: SlotType<ItemHandle<T>>,
133        {
134            PooledQueue {
135                inner: Pooled::new_from(
136                    Queue::with_slot(size),
137                    BoxedBuffer::new(arena_size),
138                    Queue::with_slot(arena_size),
139                ),
140            }
141        }
142    }
143
144    impl<T, S> MPMCQueue for PooledQueue<T, S>
145    where
146        S: SlotType<ItemHandle<T>>,
147    {
148        type Item = T;
149
150        fn push(&self, item: Self::Item) -> Result<(), Self::Item> {
151            self.inner.push(item)
152        }
153
154        fn pop(&self) -> Option<Self::Item> {
155            self.inner.pop()
156        }
157
158        fn len(&self) -> usize {
159            self.inner.len()
160        }
161
162        fn capacity(&self) -> usize {
163            self.inner.capacity()
164        }
165    }
166}