kernel/collections/
ring_buffer.rs1use crate::collections::queue;
8
9pub struct RingBuffer<'a, T: 'a> {
10 ring: &'a mut [T],
11 head: usize,
12 tail: usize,
13}
14
15impl<'a, T: Copy> RingBuffer<'a, T> {
16 pub fn new(ring: &'a mut [T]) -> RingBuffer<'a, T> {
17 RingBuffer {
18 head: 0,
19 tail: 0,
20 ring,
21 }
22 }
23
24 pub fn available_len(&self) -> usize {
26 self.ring.len().saturating_sub(1 + queue::Queue::len(self))
29 }
30
31 pub fn as_slices(&'a self) -> (Option<&'a [T]>, Option<&'a [T]>) {
41 if self.head < self.tail {
42 (Some(&self.ring[self.head..self.tail]), None)
43 } else if self.head > self.tail {
44 let (left, right) = self.ring.split_at(self.head);
45 (
46 Some(right),
47 if self.tail == 0 {
48 None
49 } else {
50 Some(&left[..self.tail])
51 },
52 )
53 } else {
54 (None, None)
55 }
56 }
57}
58
59impl<T: Copy> queue::Queue<T> for RingBuffer<'_, T> {
60 fn has_elements(&self) -> bool {
61 self.head != self.tail
62 }
63
64 fn is_full(&self) -> bool {
65 self.head == ((self.tail + 1) % self.ring.len())
66 }
67
68 fn len(&self) -> usize {
69 if self.tail > self.head {
70 self.tail - self.head
71 } else if self.tail < self.head {
72 (self.ring.len() - self.head) + self.tail
73 } else {
74 0
76 }
77 }
78
79 fn enqueue(&mut self, val: T) -> bool {
80 if self.is_full() {
81 false
83 } else {
84 self.ring[self.tail] = val;
85 self.tail = (self.tail + 1) % self.ring.len();
86 true
87 }
88 }
89
90 fn push(&mut self, val: T) -> Option<T> {
91 let result = if self.is_full() {
92 let val = self.ring[self.head];
93 self.head = (self.head + 1) % self.ring.len();
94 Some(val)
95 } else {
96 None
97 };
98
99 self.ring[self.tail] = val;
100 self.tail = (self.tail + 1) % self.ring.len();
101 result
102 }
103
104 fn dequeue(&mut self) -> Option<T> {
105 if self.has_elements() {
106 let val = self.ring[self.head];
107 self.head = (self.head + 1) % self.ring.len();
108 Some(val)
109 } else {
110 None
111 }
112 }
113
114 fn remove_first_matching<F>(&mut self, f: F) -> Option<T>
122 where
123 F: Fn(&T) -> bool,
124 {
125 let len = self.ring.len();
126 let mut slot = self.head;
127 while slot != self.tail {
128 if f(&self.ring[slot]) {
129 let val = self.ring[slot];
131
132 let mut next_slot = (slot + 1) % len;
133 while next_slot != self.tail {
135 self.ring[slot] = self.ring[next_slot];
136 slot = next_slot;
137 next_slot = (next_slot + 1) % len;
138 }
139 self.tail = slot;
140 return Some(val);
141 }
142 slot = (slot + 1) % len;
143 }
144 None
145 }
146
147 fn empty(&mut self) {
148 self.head = 0;
149 self.tail = 0;
150 }
151
152 fn retain<F>(&mut self, mut f: F)
153 where
154 F: FnMut(&T) -> bool,
155 {
156 let len = self.ring.len();
157 let mut src = self.head;
159 let mut dst = self.head;
161
162 while src != self.tail {
163 if f(&self.ring[src]) {
164 if src != dst {
167 self.ring[dst] = self.ring[src];
168 }
169 dst = (dst + 1) % len;
170 }
171 src = (src + 1) % len;
172 }
173
174 self.tail = dst;
175 }
176}
177
178#[cfg(test)]
179mod test {
180 use super::super::queue::Queue;
181 use super::RingBuffer;
182
183 #[test]
184 fn test_enqueue_dequeue() {
185 const LEN: usize = 10;
186 let mut ring = [0; LEN];
187 let mut buf = RingBuffer::new(&mut ring);
188
189 for _ in 0..2 * LEN {
190 assert!(buf.enqueue(42));
191 assert_eq!(buf.len(), 1);
192 assert!(buf.has_elements());
193
194 assert_eq!(buf.dequeue(), Some(42));
195 assert_eq!(buf.len(), 0);
196 assert!(!buf.has_elements());
197 }
198 }
199
200 #[test]
201 fn test_push() {
202 const LEN: usize = 10;
203 const MAX: usize = 100;
204 let mut ring = [0; LEN + 1];
205 let mut buf = RingBuffer::new(&mut ring);
206
207 for i in 0..LEN {
208 assert_eq!(buf.len(), i);
209 assert!(!buf.is_full());
210 assert_eq!(buf.push(i), None);
211 assert!(buf.has_elements());
212 }
213
214 for i in LEN..MAX {
215 assert!(buf.is_full());
216 assert_eq!(buf.push(i), Some(i - LEN));
217 }
218
219 for i in 0..LEN {
220 assert!(buf.has_elements());
221 assert_eq!(buf.len(), LEN - i);
222 assert_eq!(buf.dequeue(), Some(MAX - LEN + i));
223 assert!(!buf.is_full());
224 }
225
226 assert!(!buf.has_elements());
227 }
228
229 fn enqueue_iota(buf: &mut RingBuffer<usize>, len: usize) {
233 for i in 1..len {
234 assert!(!buf.is_full());
235 assert!(buf.enqueue(i));
236 assert!(buf.has_elements());
237 assert_eq!(buf.len(), i);
238 }
239
240 assert!(buf.is_full());
241 assert!(!buf.enqueue(0));
242 assert!(buf.has_elements());
243 }
244
245 fn dequeue_iota(buf: &mut RingBuffer<usize>, len: usize) {
249 for i in 1..len {
250 assert!(buf.has_elements());
251 assert_eq!(buf.len(), len - i);
252 assert_eq!(buf.dequeue(), Some(i));
253 assert!(!buf.is_full());
254 }
255
256 assert!(!buf.has_elements());
257 assert_eq!(buf.len(), 0);
258 }
259
260 fn move_head(buf: &mut RingBuffer<usize>, count: usize) {
264 assert!(!buf.has_elements());
265 assert_eq!(buf.len(), 0);
266
267 for _ in 0..count {
268 assert!(buf.enqueue(0));
269 assert_eq!(buf.dequeue(), Some(0));
270 }
271
272 assert!(!buf.has_elements());
273 assert_eq!(buf.len(), 0);
274 }
275
276 #[test]
277 fn test_fill_once() {
278 const LEN: usize = 10;
279 let mut ring = [0; LEN];
280 let mut buf = RingBuffer::new(&mut ring);
281
282 assert!(!buf.has_elements());
283 assert_eq!(buf.len(), 0);
284
285 enqueue_iota(&mut buf, LEN);
286 dequeue_iota(&mut buf, LEN);
287 }
288
289 #[test]
290 fn test_refill() {
291 const LEN: usize = 10;
292 let mut ring = [0; LEN];
293 let mut buf = RingBuffer::new(&mut ring);
294
295 for _ in 0..10 {
296 enqueue_iota(&mut buf, LEN);
297 dequeue_iota(&mut buf, LEN);
298 }
299 }
300
301 #[test]
302 fn test_retain() {
303 const LEN: usize = 10;
304 let mut ring = [0; LEN];
305 let mut buf = RingBuffer::new(&mut ring);
306
307 move_head(&mut buf, LEN - 2);
308 enqueue_iota(&mut buf, LEN);
309
310 buf.retain(|x| x % 2 == 1);
311 assert_eq!(buf.len(), LEN / 2);
312
313 assert_eq!(buf.dequeue(), Some(1));
314 assert_eq!(buf.dequeue(), Some(3));
315 assert_eq!(buf.dequeue(), Some(5));
316 assert_eq!(buf.dequeue(), Some(7));
317 assert_eq!(buf.dequeue(), Some(9));
318 assert_eq!(buf.dequeue(), None);
319 }
320}