BufferPool

Struct BufferPool 

Source
pub struct BufferPool { /* private fields */ }
Expand description

Thread-safe pool of pre-allocated pinned buffers.

Pre-allocates all buffers during construction and pins them in memory, making them immediately ready for io_uring operations. This eliminates allocation overhead and ensures predictable performance.

§Thread Safety

BufferPool is Send and Sync - internal synchronization is handled through a Mutex protecting the pool state.

§Memory Management

All buffers are pre-allocated and remain allocated for the pool’s lifetime. This provides predictable memory usage but requires careful sizing.

§Examples

use safer_ring::pool::BufferPool;

let pool = BufferPool::new(10, 4096);
if let Some(buffer) = pool.try_get().unwrap() {
    // Use buffer for I/O operations
    // Buffer automatically returns to pool on drop
}

Implementations§

Source§

impl BufferPool

Source

pub fn new(capacity: usize, buffer_size: usize) -> Self

Create a new buffer pool with specified capacity and buffer size.

All buffers are pre-allocated and pinned during construction.

§Arguments
  • capacity - Number of buffers to pre-allocate (must be > 0)
  • buffer_size - Size of each buffer in bytes (must be > 0)
§Panics

Panics if capacity or buffer_size is zero.

Source

pub fn with_factory<F>(capacity: usize, buffer_factory: F) -> Self
where F: FnMut() -> PinnedBuffer<[u8]>,

Create a buffer pool with custom buffer initialization.

Allows more control over buffer initialization, such as pre-filling buffers with specific patterns.

§Arguments
  • capacity - Number of buffers to create
  • buffer_factory - Closure that creates each buffer
§Panics

Panics if buffers have inconsistent sizes.

Source

pub fn try_get(&self) -> Result<Option<PooledBuffer>>

Try to get a buffer from the pool.

Returns Some(PooledBuffer) if available, None if pool is empty. Never blocks and never allocates new buffers.

Source

pub fn try_get_fast(&self) -> Result<Option<PooledBuffer>>

Fast path buffer acquisition with minimal locking.

This is an optimized version that uses atomic operations where possible to reduce lock contention in high-throughput scenarios.

Source

pub fn get(&self) -> Option<PooledBuffer>

Get a buffer from the pool.

Returns Some(PooledBuffer) if available, None if pool is empty. This is a convenience method that unwraps the Result from try_get.

Source

pub fn get_blocking(&self) -> Result<PooledBuffer>

Get a buffer from the pool, blocking until one becomes available.

This method blocks the current thread until a buffer is returned. Uses exponential backoff to reduce CPU usage while waiting.

§Performance Note

For high-performance applications, consider using try_get() in a loop with your own scheduling strategy rather than this blocking method.

Source

pub fn capacity(&self) -> usize

Get the total capacity of the pool.

This is a lock-free operation since capacity is immutable.

Source

pub fn available(&self) -> Result<usize>

Get the number of available buffers.

Source

pub fn in_use(&self) -> Result<usize>

Get the number of buffers currently in use.

Source

pub fn buffer_size(&self) -> usize

Get the size of each buffer in the pool.

This is a lock-free operation since buffer size is immutable.

Source

pub fn stats(&self) -> PoolStats

Get comprehensive statistics about the pool.

Returns detailed information about pool usage and allocation patterns. Takes a single lock to ensure all statistics are consistent.

Source

pub fn is_empty(&self) -> Result<bool>

Check if the pool is empty (no available buffers).

Source

pub fn is_full(&self) -> Result<bool>

Check if the pool is full (all buffers available).

Source

pub fn snapshot(&self) -> Result<(usize, usize, bool, bool)>

Get a snapshot of current pool state in a single lock operation.

More efficient than calling multiple methods separately when you need multiple pieces of information about the pool state.

Trait Implementations§

Auto Trait Implementations§

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