Skip to main content

ZeroPool

Struct ZeroPool 

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

A user-space byte allocator with size-class bucketing and thread-local caching.

§Architecture

Thread 1            Thread 2            Thread N
┌────────────┐     ┌────────────┐     ┌────────────┐
│ TLS Cache  │     │ TLS Cache  │     │ TLS Cache  │  ← Lock-free
│ [class 0]  │     │ [class 0]  │     │ [class 0]  │    per-class
│ [class 1]  │     │ [class 1]  │     │ [class 1]  │    LIFO caches
│   ...      │     │   ...      │     │   ...      │
└─────┬──────┘     └─────┬──────┘     └─────┬──────┘
      │ batch             │ batch             │ batch
      └──────────┬───────┴───────────────────┘
                 │
         ┌───────▼────────┐
         │  Shared Pool   │
         │ (lock-free)    │
         │                │
         │ [4KB  queue]   │  ArrayQueue per class
         │ [16KB queue]   │  CAS-based push/pop
         │ [64KB queue]   │  No mutex needed
         │ [256KB queue]  │
         │ [1MB  queue]   │
         │ [4MB  queue]   │
         │ [16MB queue]   │
         │ [64MB queue]   │
         └────────────────┘

Implementations§

Source§

impl ZeroPool

Source

pub fn new() -> Self

Create a new allocator with system-aware defaults.

Chain configuration methods to customize before use:

use zeropool::ZeroPool;

// Defaults
let pool = ZeroPool::new();

// Custom
let pool = ZeroPool::new()
    .min_buffer_size(4096)
    .tls_cache_size(8)
    .max_buffers_per_class(64)
    .batch_size(4)
    .track_stats(true);
Source

pub fn allocator(self, alloc: impl Allocator) -> Self

Set a custom allocator for buffer creation.

Default: HeapAllocator (standard Vec::with_capacity).

use zeropool::{Allocator, ZeroPool};

struct MyAllocator;
impl Allocator for MyAllocator {
    fn allocate(&self, capacity: usize) -> Vec<u8> {
        Vec::with_capacity(capacity)
    }
}

let pool = ZeroPool::new().allocator(MyAllocator);
Source

pub fn min_buffer_size(self, size: usize) -> Self

Set the minimum buffer size to keep in the pool.

Buffers smaller than this are discarded on dealloc. Default: 4KB

Source

pub fn tls_cache_size(self, size: usize) -> Self

Set the number of buffers kept in thread-local cache per size class.

Higher values reduce shared pool access but increase per-thread memory. Also recomputes batch size (half of TLS cache, min 2) unless .batch_size() is called afterwards to override. Default: 2–8 based on CPU count

Source

pub fn max_buffers_per_class(self, count: usize) -> Self

Set the maximum number of buffers per size class in the shared pool.

Default: 32–128 based on CPU count

Source

pub fn pinned_memory(self, enabled: bool) -> Self

Enable pinned memory (mlock) for allocated buffers.

Locks buffers in RAM to prevent swapping. Default: false

Source

pub fn batch_size(self, size: usize) -> Self

Set the batch size for TLS ↔ shared pool transfers.

When a thread-local cache misses, this many buffers are moved at once from the shared pool (magazine-style). Default: half of TLS cache size (min 2)

Source

pub fn track_stats(self, enabled: bool) -> Self

Enable or disable runtime statistics tracking.

Disabled by default because hot-path atomic counters are measurable overhead in tight allocation loops. Enable this when you need stats() to report allocation counters.

Source

pub fn alloc(&self, size: usize) -> Buf<'_>

Allocate a buffer of at least size bytes.

Returns a Buf that automatically deallocates back to the pool on drop.

§Performance
  1. Fastest: TLS cache pop (lock-free, ~24ns)
  2. Fast: Batch refill from shared pool (lock-free CAS)
  3. Cold: Fresh allocation via the configured Allocator
§Example
use zeropool::ZeroPool;

let pool = ZeroPool::new();
let mut buf = pool.alloc(1024);
buf[0] = 42;
Source

pub fn warm(&self, count: usize, size: usize)

Warm up the pool by pre-allocating buffers for the given size class.

§Example
use zeropool::ZeroPool;

let pool = ZeroPool::new().min_buffer_size(0).track_stats(true);
pool.warm(16, 64 * 1024); // 16 × 64KB buffers
Source

pub fn len(&self) -> usize

Total number of buffers across all shared size classes.

Does not include thread-local cached buffers.

Source

pub fn is_empty(&self) -> bool

Whether all shared size classes are empty.

Does not check thread-local caches.

Source

pub fn drain(&self)

Drain all buffers from all shared size classes.

Thread-local caches are NOT cleared.

Source

pub fn stats(&self) -> Stats

Point-in-time snapshot of allocator statistics.

§Example
use zeropool::ZeroPool;

let pool = ZeroPool::new().min_buffer_size(0).track_stats(true);
let buf = pool.alloc(4096);
drop(buf);

let s = pool.stats();
assert_eq!(s.gets, 1);
assert_eq!(s.puts, 1);
println!("{s}");
Source

pub fn reset_stats(&self)

Reset all performance counters to zero.

Trait Implementations§

Source§

impl Debug for ZeroPool

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for ZeroPool

Source§

fn default() -> Self

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

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.