pub struct SpscRing<T, const N: usize> { /* private fields */ }Expand description
A fixed-capacity SPSC ring buffer that holds items of type T.
The const generic N sets the number of backing slots. One slot is kept as
a sentinel, so the buffer holds at most N - 1 items concurrently.
§Example
use fin_stream::ring::SpscRing;
let ring: SpscRing<u64, 8> = SpscRing::new();
ring.push(42).unwrap();
assert_eq!(ring.pop().unwrap(), 42);Implementations§
Source§impl<T, const N: usize> SpscRing<T, N>
impl<T, const N: usize> SpscRing<T, N>
Sourcepub fn push(&self, item: T) -> Result<(), StreamError>
pub fn push(&self, item: T) -> Result<(), StreamError>
Push an item into the buffer.
Returns Err(StreamError::RingBufferFull) if the buffer is full.
Never panics.
§Complexity: O(1), allocation-free.
Sourcepub fn pop(&self) -> Result<T, StreamError>
pub fn pop(&self) -> Result<T, StreamError>
Pop an item from the buffer.
Returns Err(StreamError::RingBufferEmpty) if the buffer is empty.
Never panics.
§Complexity: O(1), allocation-free.
Sourcepub fn try_push_or_drop(&self, item: T) -> bool
pub fn try_push_or_drop(&self, item: T) -> bool
Push an item, silently dropping it and returning false if the buffer is full.
Unlike push, this never returns an error — it accepts data loss
under backpressure. Suitable for non-critical metrics or telemetry where
occasional drops are preferable to blocking or erroring.
Returns true if the item was enqueued, false if it was dropped.
§Complexity: O(1), allocation-free.
Sourcepub fn peek_clone(&self) -> Option<T>where
T: Clone,
pub fn peek_clone(&self) -> Option<T>where
T: Clone,
Sourcepub fn peek_all(&self) -> Vec<T>where
T: Clone,
pub fn peek_all(&self) -> Vec<T>where
T: Clone,
Clone all items currently in the ring into a Vec, in FIFO order,
without consuming them.
Only safe to call when no producer/consumer pair is active (i.e., before
calling split()). The ring is left unchanged.
§Complexity: O(n).
Sourcepub fn peek_newest(&self) -> Option<T>where
T: Copy,
pub fn peek_newest(&self) -> Option<T>where
T: Copy,
Returns a copy of the most recently pushed item without consuming it,
or None if the ring is empty.
“Newest” is the item at tail - 1 — the last item that was pushed.
Unlike pop (which removes from the head), this leaves
the ring unchanged.
Sourcepub fn peek_oldest(&self) -> Option<T>where
T: Copy,
pub fn peek_oldest(&self) -> Option<T>where
T: Copy,
Peek at the oldest item in the ring (the one that would be returned next by pop)
without removing it.
Returns None when the ring is empty.
Sourcepub fn fill_ratio(&self) -> f64
pub fn fill_ratio(&self) -> f64
Current fill level as a fraction of capacity: len / capacity.
Returns 0.0 when empty and 1.0 when full.
Sourcepub fn has_capacity(&self, n: usize) -> bool
pub fn has_capacity(&self, n: usize) -> bool
Returns true if there is enough free space to push n more items.
Equivalent to self.len() + n <= self.capacity().
Sourcepub fn utilization_pct(&self) -> f64
pub fn utilization_pct(&self) -> f64
Fill level as a percentage of capacity: fill_ratio() * 100.0.
Returns 0.0 when empty and 100.0 when full.
Sourcepub fn remaining_capacity(&self) -> usize
pub fn remaining_capacity(&self) -> usize
Number of additional items that can be pushed before the buffer is full.
Sourcepub fn is_nearly_full(&self, threshold: f64) -> bool
pub fn is_nearly_full(&self, threshold: f64) -> bool
Returns true if the fill ratio exceeds threshold (a value in [0.0, 1.0]).
For example, is_nearly_full(0.9) returns true when the buffer is ≥ 90% full.
Sourcepub fn first(&self) -> Option<T>where
T: Copy,
pub fn first(&self) -> Option<T>where
T: Copy,
Returns a copy of the oldest item (front) without removing it.
Returns None if the buffer is empty. Only valid before calling split().
Sourcepub fn peek_front(&self) -> Option<&T>
pub fn peek_front(&self) -> Option<&T>
Returns a reference to the oldest item (front) without removing it.
Returns None if the buffer is empty. Only valid before calling split().
Sourcepub fn peek_back(&self) -> Option<&T>
pub fn peek_back(&self) -> Option<&T>
Returns a reference to the newest item (back) without removing it.
Returns None if the buffer is empty. Only valid before calling split().
Sourcepub fn drain(&self) -> Vec<T>
pub fn drain(&self) -> Vec<T>
Drain all items currently in the ring into a Vec, in FIFO order.
Only safe to call when no producer/consumer pair is active (i.e., before
calling split()).
§Complexity: O(n).
Sourcepub fn drain_into(&self, buf: &mut Vec<T>)
pub fn drain_into(&self, buf: &mut Vec<T>)
Drain all items from the ring into buf in FIFO order, appending to
any existing contents of buf.
Only safe to call when no producer/consumer pair is active (i.e., before
calling split()). Useful for draining into a pre-allocated buffer to
avoid allocation.
§Complexity: O(n).
Sourcepub fn to_vec_cloned(&self) -> Vec<T>where
T: Clone,
pub fn to_vec_cloned(&self) -> Vec<T>where
T: Clone,
Returns a snapshot of all items in FIFO order without removing them.
Only valid before calling split(). Requires T: Clone.
§Complexity: O(n).
Sourcepub fn to_vec_sorted(&self) -> Vec<T>
pub fn to_vec_sorted(&self) -> Vec<T>
Returns a sorted Vec of all ring elements, cloned.
The ring itself is not modified. An empty ring returns an empty vec.
§Complexity: O(n log n).
Sourcepub fn min_cloned(&self) -> Option<T>
pub fn min_cloned(&self) -> Option<T>
Returns the minimum item in the ring by cloning, without removing any items.
Returns None if the ring is empty. Only valid before calling split().
§Complexity: O(n).
Sourcepub fn max_cloned(&self) -> Option<T>
pub fn max_cloned(&self) -> Option<T>
Returns the maximum item in the ring by cloning, without removing any items.
Returns None if the ring is empty. Only valid before calling split().
§Complexity: O(n).
Sourcepub fn count_if<F>(&self, predicate: F) -> usize
pub fn count_if<F>(&self, predicate: F) -> usize
Count items in the ring that satisfy predicate, without removing them.
Only valid before calling split(). Requires T to be readable via shared ref.
§Complexity: O(n).
Sourcepub fn peek_nth(&self, n: usize) -> Option<T>where
T: Clone,
pub fn peek_nth(&self, n: usize) -> Option<T>where
T: Clone,
Returns the nth oldest element in the ring (0 = oldest), cloned.
Returns None if n is out of bounds.
§Complexity: O(1).
Sourcepub fn min_cloned_by<F, K>(&self, key: F) -> Option<T>
pub fn min_cloned_by<F, K>(&self, key: F) -> Option<T>
Returns the element for which key(element) is minimum, cloned.
Returns None if the ring is empty.
§Complexity: O(n).
Sourcepub fn max_cloned_by<F, K>(&self, key: F) -> Option<T>
pub fn max_cloned_by<F, K>(&self, key: F) -> Option<T>
Returns the element for which key(element) is maximum, cloned.
Returns None if the ring is empty.
§Complexity: O(n).
Sourcepub fn contains_cloned(&self, value: &T) -> bool
pub fn contains_cloned(&self, value: &T) -> bool
Returns true if the ring contains an element equal to value.
§Complexity: O(n).
Sourcepub fn average_cloned(&self) -> Option<f64>
pub fn average_cloned(&self) -> Option<f64>
Arithmetic mean of all elements in the ring, as f64.
Returns None if the ring is empty.
§Complexity: O(n).
Sourcepub fn sum_cloned(&self) -> T
pub fn sum_cloned(&self) -> T
Sum of all elements currently in the ring, cloned out of initialized slots.
Returns T::default() (typically 0) when the ring is empty.
§Complexity: O(n).
Sourcepub fn split(self) -> (SpscProducer<T, N>, SpscConsumer<T, N>)
pub fn split(self) -> (SpscProducer<T, N>, SpscConsumer<T, N>)
Split the ring into a thread-safe producer/consumer pair.
The original SpscRing is consumed. Both halves hold an Arc to the
shared backing store.
§Example
use fin_stream::ring::SpscRing;
use std::thread;
let ring: SpscRing<u64, 64> = SpscRing::new();
let (prod, cons) = ring.split();
let handle = thread::spawn(move || {
prod.push(99).unwrap();
});
handle.join().unwrap();
assert_eq!(cons.pop().unwrap(), 99u64);