Skip to content

Commit e817767

Browse files
committed
implement returning of old elements on enqueue
1 parent 05b4975 commit e817767

File tree

5 files changed

+51
-37
lines changed

5 files changed

+51
-37
lines changed

src/lib.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ mod tests {
6464
const capacity: usize = 8;
6565
fn test_neg_index(mut b: impl RingBuffer<usize>) {
6666
for i in 0..capacity + 2 {
67-
b.push(i);
67+
let _ = b.push(i);
6868
assert_eq!(b.get_signed(-1), Some(&i));
6969
}
7070
}
@@ -114,9 +114,9 @@ mod tests {
114114
fn run_test_len() {
115115
fn test_len(mut b: impl RingBuffer<i32>) {
116116
assert_eq!(0, b.len());
117-
b.push(1);
117+
let _ = b.push(1);
118118
assert_eq!(1, b.len());
119-
b.push(2);
119+
let _ = b.push(2);
120120
assert_eq!(2, b.len())
121121
}
122122

@@ -129,14 +129,14 @@ mod tests {
129129
fn run_test_len_wrap() {
130130
fn test_len_wrap(mut b: impl RingBuffer<i32>) {
131131
assert_eq!(0, b.len());
132-
b.push(1);
132+
let _ = b.push(1);
133133
assert_eq!(1, b.len());
134-
b.push(2);
134+
let _ = b.push(2);
135135
assert_eq!(2, b.len());
136136
// Now we are wrapping
137-
b.push(3);
137+
let _ = b.push(3);
138138
assert_eq!(2, b.len());
139-
b.push(4);
139+
let _ = b.push(4);
140140
assert_eq!(2, b.len());
141141
}
142142

@@ -1033,15 +1033,15 @@ mod tests {
10331033
#[test]
10341034
fn run_test_enqueue_dequeue_push() {
10351035
fn test_enqueue_dequeue_push(mut b: impl RingBuffer<i32>) {
1036-
b.enqueue(0);
1037-
b.enqueue(1);
1036+
b.push(0);
1037+
b.push(1);
10381038

10391039
assert_eq!(b.dequeue(), Some(0));
10401040
assert_eq!(b.dequeue(), Some(1));
10411041
assert_eq!(b.dequeue(), None);
10421042

1043-
b.enqueue(0);
1044-
b.enqueue(1);
1043+
b.push(0);
1044+
b.push(1);
10451045

10461046
assert_eq!(b.dequeue(), Some(0));
10471047
assert_eq!(b.dequeue(), Some(1));

src/ringbuffer_trait.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,18 @@ pub unsafe trait RingBuffer<T>:
7676
unsafe fn ptr_buffer_size(rb: *const Self) -> usize;
7777

7878
/// Pushes a value onto the buffer. Cycles around if capacity is reached.
79-
fn push(&mut self, value: T);
79+
///
80+
/// Does not return the oldest item in the buffer if the buffer is full, to more closely match the api of `push` on `Vec` and `VecDeque`.
81+
/// If that property is desired, use [`dequeue`](RingBuffer::dequeue)
82+
#[inline]
83+
fn push(&mut self, value: T) {
84+
let _ = self.enqueue(value);
85+
}
8086

8187
/// alias for [`push`](RingBuffer::push), forming a more natural counterpart to [`dequeue`](RingBuffer::dequeue)
82-
fn enqueue(&mut self, value: T) {
83-
self.push(value);
84-
}
88+
///
89+
/// If the buffer is full, returns the oldest item in the buffer that was just removed to make room for the pushed value.
90+
fn enqueue(&mut self, value: T) -> Option<T>;
8591

8692
/// dequeues the top item off the ringbuffer, and moves this item out.
8793
fn dequeue(&mut self) -> Option<T>;

src/with_alloc/alloc_ringbuffer.rs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ impl<T: Clone> Clone for AllocRingBuffer<T> {
163163
debug_assert_ne!(self.capacity, 0);
164164

165165
let mut new = Self::new(self.capacity);
166-
self.iter().cloned().for_each(|i| new.push(i));
166+
new.extend(self.iter().cloned());
167167
new
168168
}
169169
}
@@ -229,20 +229,15 @@ unsafe impl<T> RingBuffer<T> for AllocRingBuffer<T> {
229229
impl_ringbuffer!(readptr, writeptr);
230230

231231
#[inline]
232-
fn push(&mut self, value: T) {
232+
fn enqueue(&mut self, value: T) -> Option<T> {
233+
let mut ret = None;
234+
233235
if self.is_full() {
234236
// mask with and is allowed here because size is always a power of two
235237
let previous_value =
236238
unsafe { ptr::read(get_unchecked_mut(self, mask_and(self.size, self.readptr))) };
237239

238-
// make sure we drop whatever is being overwritten
239-
// SAFETY: the buffer is full, so this must be initialized
240-
// : also, index has been masked
241-
// make sure we drop because it won't happen automatically
242-
unsafe {
243-
drop(previous_value);
244-
}
245-
240+
ret = Some(previous_value);
246241
self.readptr += 1;
247242
}
248243

@@ -254,6 +249,8 @@ unsafe impl<T> RingBuffer<T> for AllocRingBuffer<T> {
254249
}
255250

256251
self.writeptr += 1;
252+
253+
ret
257254
}
258255

259256
fn dequeue(&mut self) -> Option<T> {
@@ -392,7 +389,7 @@ mod tests {
392389
// messes up
393390
for _ in 0..100 {
394391
for i in 0..NUM_VALS {
395-
rb.enqueue(i);
392+
let _ = rb.enqueue(i);
396393
}
397394
assert!(rb.is_full());
398395

@@ -420,7 +417,9 @@ mod tests {
420417
#[test]
421418
fn test_extend() {
422419
let mut buf = AllocRingBuffer::<u8>::new(4);
423-
(0..4).for_each(|_| buf.push(0));
420+
(0..4).for_each(|_| {
421+
let _ = buf.push(0);
422+
});
424423

425424
let new_data = [0, 1, 2];
426425
buf.extend(new_data);
@@ -437,7 +436,9 @@ mod tests {
437436
#[test]
438437
fn test_extend_with_overflow() {
439438
let mut buf = AllocRingBuffer::<u8>::new(8);
440-
(0..8).for_each(|_| buf.push(0));
439+
(0..8).for_each(|_| {
440+
let _ = buf.push(0);
441+
});
441442

442443
let new_data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
443444
buf.extend(new_data);

src/with_alloc/vecdeque.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,9 @@ unsafe impl<T> RingBuffer<T> for GrowableAllocRingBuffer<T> {
186186
self.pop_front()
187187
}
188188

189-
fn push(&mut self, value: T) {
189+
fn enqueue(&mut self, value: T) -> Option<T> {
190190
self.push_back(value);
191+
None
191192
}
192193

193194
fn fill_with<F: FnMut() -> T>(&mut self, mut f: F) {

src/with_const_generics.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ impl<T, const CAP: usize> Drop for ConstGenericRingBuffer<T, CAP> {
138138
impl<T: Clone, const CAP: usize> Clone for ConstGenericRingBuffer<T, CAP> {
139139
fn clone(&self) -> Self {
140140
let mut new = ConstGenericRingBuffer::<T, CAP>::new();
141-
self.iter().cloned().for_each(|i| new.push(i));
141+
new.extend(self.iter().cloned());
142142
new
143143
}
144144
}
@@ -265,7 +265,9 @@ unsafe impl<T, const CAP: usize> RingBuffer<T> for ConstGenericRingBuffer<T, CAP
265265
impl_ringbuffer!(readptr, writeptr);
266266

267267
#[inline]
268-
fn push(&mut self, value: T) {
268+
fn enqueue(&mut self, value: T) -> Option<T> {
269+
let mut ret = None;
270+
269271
if self.is_full() {
270272
let previous_value = mem::replace(
271273
&mut self.buf[crate::mask_modulo(CAP, self.readptr)],
@@ -275,14 +277,14 @@ unsafe impl<T, const CAP: usize> RingBuffer<T> for ConstGenericRingBuffer<T, CAP
275277
// SAFETY: the buffer is full, so this must be initialized
276278
// : also, index has been masked
277279
// make sure we drop because it won't happen automatically
278-
unsafe {
279-
drop(previous_value.assume_init());
280-
}
280+
ret = Some(unsafe { previous_value.assume_init() });
281281
self.readptr += 1;
282282
}
283283
let index = crate::mask_modulo(CAP, self.writeptr);
284284
self.buf[index] = MaybeUninit::new(value);
285285
self.writeptr += 1;
286+
287+
ret
286288
}
287289

288290
fn dequeue(&mut self) -> Option<T> {
@@ -365,7 +367,7 @@ mod tests {
365367
// messes up
366368
for _ in 0..100 {
367369
for i in 0..NUM_VALS {
368-
rb.enqueue(i);
370+
let _ = rb.enqueue(i);
369371
}
370372
assert!(rb.is_full());
371373

@@ -387,7 +389,9 @@ mod tests {
387389
#[test]
388390
fn test_extend() {
389391
let mut buf = ConstGenericRingBuffer::<u8, 4>::new();
390-
(0..4).for_each(|_| buf.push(0));
392+
(0..4).for_each(|_| {
393+
let _ = buf.push(0);
394+
});
391395

392396
let new_data = [0, 1, 2];
393397
buf.extend(new_data);
@@ -404,7 +408,9 @@ mod tests {
404408
#[test]
405409
fn test_extend_with_overflow() {
406410
let mut buf = ConstGenericRingBuffer::<u8, 8>::new();
407-
(0..8).for_each(|_| buf.push(0));
411+
(0..8).for_each(|_| {
412+
let _ = buf.push(0);
413+
});
408414

409415
let new_data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
410416
buf.extend(new_data);

0 commit comments

Comments
 (0)