bufferring/masking/
mod.rs1use core::fmt::{self, Debug, Display};
4use core::num::Wrapping;
5
6use crate::{storage::Slot, RingBuffer, Storage};
7
8pub mod prop;
9
10mod tests;
11
12pub struct MaskingBuffer<S: Storage + ?Sized> {
20 cur: Wrapping<usize>,
25
26 len: usize,
34
35 data: S,
40}
41
42impl<S: Storage> MaskingBuffer<S> {
45 pub fn new(storage: S) -> Result<Self, Error> {
50 if storage.cap().is_power_of_two() {
51 Ok(unsafe { Self::new_unchecked(storage) })
53 } else {
54 Err(Error::NotPowerOfTwo)
55 }
56 }
57
58 pub unsafe fn new_unchecked(storage: S) -> Self {
64 Self { cur: Wrapping(0), len: 0, data: storage }
65 }
66}
67
68impl<S: Storage + ?Sized> MaskingBuffer<S> {
69 fn mask(&self, off: Wrapping<usize>) -> usize {
71 off.0 & (self.cap() - 1)
72 }
73}
74
75impl<S: Storage + ?Sized> RingBuffer for MaskingBuffer<S> {
76 type Item = S::Item;
77
78 fn cap(&self) -> usize {
79 self.data.cap()
80 }
81
82 fn len(&self) -> usize {
83 self.len
84 }
85
86 fn get(&self, off: usize) -> Option<&Self::Item> {
87 if off >= self.len { return None; }
88 let off = self.mask(self.cur + Wrapping(off));
92 Some(unsafe { self.data.get().get_unchecked(off).get_ref() })
93 }
94
95 fn get_mut(&mut self, off: usize) -> Option<&mut Self::Item> {
96 if off >= self.len { return None; }
97 let off = self.mask(self.cur + Wrapping(off));
101 Some(unsafe { self.data.get_mut().get_unchecked_mut(off).get_mut() })
102 }
103
104 unsafe fn get_disjoint_mut(&self, off: usize) -> &mut Self::Item {
105 let off = self.mask(self.cur + Wrapping(off));
110 unsafe { self.data.get().get_unchecked(off).get_int_mut() }
111 }
112
113 fn enqueue(&mut self, item: Self::Item) -> Option<Self::Item> {
114 let is_full = self.is_full();
115 let off = self.mask(self.cur + Wrapping(self.len));
118 let ptr = unsafe { self.data.get_mut().get_unchecked_mut(off) };
119
120 let res = is_full.then(|| {
121 self.len -= 1;
124 self.cur += 1;
125 unsafe { ptr.take() }
126 });
127
128 *ptr = Slot::new(item);
129
130 self.len += 1;
131
132 res
133 }
134
135 fn dequeue(&mut self) -> Option<Self::Item> {
136 if self.is_empty() { return None; }
137
138 let off = self.mask(self.cur);
142 let item = unsafe { self.data.get_mut().get_unchecked_mut(off).take() };
143
144 self.cur += 1;
145 self.len -= 1;
146 Some(item)
147 }
148
149 fn skip_one(&mut self) {
150 if self.is_empty() { return; }
151
152 let off = self.mask(self.cur + Wrapping(self.len));
156 unsafe { self.data.get_mut().get_unchecked_mut(off).drop_in_place(); }
157
158 self.cur += 1;
159 self.len -= 1;
160 }
161}
162
163impl<T: Clone, S: Storage<Item = T> + Clone> Clone for MaskingBuffer<S> {
164 fn clone(&self) -> Self {
165 let mut res = unsafe { Self::new_unchecked(self.data.clone()) };
167 for item in self.iter() {
168 res.enqueue(item.clone());
169 }
170 res
171 }
172}
173
174impl<S: Storage> Debug for MaskingBuffer<S>
175where S: Debug, S::Item: Debug {
176 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
177 struct Items<'a, S: Storage>(&'a MaskingBuffer<S>);
178
179 impl<'a, S: Storage> Debug for Items<'a, S>
180 where S::Item: Debug {
181 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
182 f.debug_list().entries(self.0.iter()).finish()
183 }
184 }
185
186 f.debug_struct("MaskingBuffer")
187 .field("cur", &self.cur)
188 .field("len", &self.len)
189 .field("data", &self.data)
190 .field("items", &Items(self))
191 .finish()
192 }
193}
194
195#[derive(Clone, PartialEq, Eq, Debug)]
197pub enum Error {
198 NotPowerOfTwo,
201}
202
203impl Display for Error {
204 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
205 match self {
206 Self::NotPowerOfTwo => write!(f,
207 "An attempt was made to create a `MaskingBuffer` with a \
208 capacity that is not a power of two"),
209 }
210 }
211}