From 3d97c6033d05c6d5b6e0682ff171f41edbcc1e8c Mon Sep 17 00:00:00 2001 From: Alexey Gerasev Date: Fri, 16 Aug 2024 11:54:31 +0700 Subject: [PATCH] Add peek methods to Consumer, bump version --- Cargo.toml | 4 ++-- src/traits/consumer.rs | 35 ++++++++++++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2cd1e49..89eaedc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,14 +7,14 @@ readme = "README.md" license = "MIT/Apache-2.0" [workspace.dependencies] -ringbuf = { path = ".", version = "0.4.2" } +ringbuf = { path = ".", version = "0.4.3" } [workspace] members = ["async", "blocking"] [package] name = "ringbuf" -version = "0.4.2" +version = "0.4.3" edition.workspace = true authors.workspace = true description = "Lock-free SPSC FIFO ring buffer with direct access to inner data" diff --git a/src/traits/consumer.rs b/src/traits/consumer.rs index 9d31724..6d33968 100644 --- a/src/traits/consumer.rs +++ b/src/traits/consumer.rs @@ -121,10 +121,21 @@ pub trait Consumer: Observer { } } - /// Removes items from the ring buffer and writes them into an uninit slice. + /// Returns the reference to the eldest item without removing it from the buffer. /// - /// Returns count of items been removed. - fn pop_slice_uninit(&mut self, elems: &mut [MaybeUninit]) -> usize { + /// Returns `None` if the ring buffer is empty. + fn try_peek(&self) -> Option<&Self::Item> { + if !self.is_empty() { + Some(unsafe { self.occupied_slices().0.get_unchecked(0).assume_init_ref() }) + } else { + None + } + } + + /// Copies items from the ring buffer to an uninit slice without removing them from the ring buffer. + /// + /// Returns a number of items being copied. + fn peek_slice_uninit(&self, elems: &mut [MaybeUninit]) -> usize { let (left, right) = self.occupied_slices(); let count = if elems.len() < left.len() { move_uninit_slice(elems, unsafe { left.get_unchecked(..elems.len()) }); @@ -141,6 +152,24 @@ pub trait Consumer: Observer { right.len() } }; + count + } + + /// Copies items from the ring buffer to a slice without removing them from the ring buffer. + /// + /// Returns a number of items being copied. + fn peek_slice(&self, elems: &mut [Self::Item]) -> usize + where + Self::Item: Copy, + { + self.peek_slice_uninit(unsafe { slice_as_uninit_mut(elems) }) + } + + /// Removes items from the ring buffer and writes them into an uninit slice. + /// + /// Returns count of items been removed. + fn pop_slice_uninit(&mut self, elems: &mut [MaybeUninit]) -> usize { + let count = self.peek_slice_uninit(elems); unsafe { self.advance_read_index(count) }; count }