Skip to main content

SpscRing

Struct SpscRing 

Source
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>

Source

pub fn new() -> Self

Construct an empty ring buffer.

Source

pub fn is_empty(&self) -> bool

Returns true if the buffer contains no items.

Source

pub fn is_full(&self) -> bool

Returns true if the buffer has no free slots.

Source

pub fn len(&self) -> usize

Number of items currently in the buffer.

Source

pub fn capacity(&self) -> usize

Maximum number of items the buffer can hold.

Source

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.
Source

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.
Source

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.
Source

pub fn peek_clone(&self) -> Option<T>
where T: Clone,

Clone the next item from the ring without removing it.

Returns None if the ring is empty. The item remains available for a subsequent pop call.

§Complexity: O(1).
Source

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).
Source

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.

Source

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.

Source

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.

Source

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().

Source

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.

Source

pub fn remaining_capacity(&self) -> usize

Number of additional items that can be pushed before the buffer is full.

Source

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.

Source

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().

Source

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().

Source

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().

Source

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).
Source

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).
Source

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).
Source

pub fn to_vec_sorted(&self) -> Vec<T>
where T: Clone + Ord,

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).
Source

pub fn min_cloned(&self) -> Option<T>
where T: Clone + Ord,

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).
Source

pub fn max_cloned(&self) -> Option<T>
where T: Clone + Ord,

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).
Source

pub fn count_if<F>(&self, predicate: F) -> usize
where F: Fn(&T) -> bool,

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).
Source

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).
Source

pub fn min_cloned_by<F, K>(&self, key: F) -> Option<T>
where T: Clone, F: Fn(&T) -> K, K: Ord,

Returns the element for which key(element) is minimum, cloned.

Returns None if the ring is empty.

§Complexity: O(n).
Source

pub fn max_cloned_by<F, K>(&self, key: F) -> Option<T>
where T: Clone, F: Fn(&T) -> K, K: Ord,

Returns the element for which key(element) is maximum, cloned.

Returns None if the ring is empty.

§Complexity: O(n).
Source

pub fn contains_cloned(&self, value: &T) -> bool
where T: Clone + PartialEq,

Returns true if the ring contains an element equal to value.

§Complexity: O(n).
Source

pub fn average_cloned(&self) -> Option<f64>
where T: Clone + Into<f64>,

Arithmetic mean of all elements in the ring, as f64.

Returns None if the ring is empty.

§Complexity: O(n).
Source

pub fn sum_cloned(&self) -> T
where T: Clone + Sum + Default,

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).
Source

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);

Trait Implementations§

Source§

impl<T, const N: usize> Default for SpscRing<T, N>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<T, const N: usize> Drop for SpscRing<T, N>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl<T: Send, const N: usize> Send for SpscRing<T, N>

Auto Trait Implementations§

§

impl<T, const N: usize> !Freeze for SpscRing<T, N>

§

impl<T, const N: usize> !RefUnwindSafe for SpscRing<T, N>

§

impl<T, const N: usize> !Sync for SpscRing<T, N>

§

impl<T, const N: usize> Unpin for SpscRing<T, N>

§

impl<T, const N: usize> UnsafeUnpin for SpscRing<T, N>

§

impl<T, const N: usize> UnwindSafe for SpscRing<T, N>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more