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 usable slots. The backing array
has exactly N elements; one is kept as a sentinel so the buffer can hold
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 new() -> Self
pub fn new() -> Self
Construct an empty ring buffer.
§Panics
Panics if N <= 1. The const generic N must be at least 2 to hold at
least one item (one slot is reserved as the full/empty sentinel). This
is an API misuse guard; it cannot be expressed as a compile-time error
with stable Rust const-generics.
§Complexity
O(N) for initialization of the backing array.
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
§Throughput note
This is the hot path. It performs one Acquire load, one array write,
and one Release store. On a modern out-of-order CPU these three
operations typically retire within a single cache line access.
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 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.
After calling split, the original SpscRing is consumed. The
producer and consumer halves each hold an Arc to the shared backing
store so the buffer is kept alive until both halves are dropped.
§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);