Skip to main content

Arena

Struct Arena 

Source
pub struct Arena<const MAX_ITEM_COUNT: usize, const MAX_ITEM_SIZE: usize> { /* private fields */ }
Expand description

A circular, allocation-free arena for reusable memory blocks.

Arena manages a fixed-capacity pool of Bytes buffers, each up to MAX_ITEM_SIZE bytes. After the pool is lazily initialized, subsequent allocations scan from an internal cursor to find a free slot, avoiding further heap allocation.

§Const Parameters

  • MAX_ITEM_COUNT — maximum number of buffers in the pool.
  • MAX_ITEM_SIZE — capacity of each individual buffer in bytes.

§How It Works

The arena maintains a vector of reference-counted buffer slots. When a caller requests memory, the arena advances its cursor through the pool looking for a slot whose reference count is zero, then hands back a Bytes handle to that slot. The cursor wraps around, giving the allocation pattern its circular behavior.

Because a Bytes handle can outlive the Arena itself (e.g. when the owning thread exits but the handle was sent elsewhere), each slot is wrapped in an Arc to keep the underlying storage alive. A separate AtomicU32 reference count tracks logical ownership independently of the Arc strong count, so the arena can reliably detect which slots are free.

§Use Case

This is useful as a replacement for repeated Arc<dyn Trait> allocations.

Implementations§

Source§

impl<const MAX_ITEM_COUNT: usize, const MAX_ITEM_SIZE: usize> Arena<MAX_ITEM_COUNT, MAX_ITEM_SIZE>

Source

pub const fn new() -> Self

Creates a new, empty Arena.

The internal buffer is not allocated until the first call to reserve.

Source

pub const fn accept<O>() -> bool

Returns true if an object of type O fits within a single slot.

Checks that both the size and alignment of O are compatible with Bytes<MAX_ITEM_SIZE>.

Source

pub fn reserve(&mut self) -> Option<UninitReservedMemory<MAX_ITEM_SIZE>>

Attempts to reserve an uninitialized slot in the arena.

On the first call, the internal buffer is lazily allocated to MAX_ITEM_COUNT slots. Subsequent calls scan from the current cursor position, wrapping around circularly, looking for a slot whose backing Arc has a strong count of 1 (meaning no outstanding ReservedMemory handles reference it).

§Returns
  • Some(UninitReservedMemory) — a handle to the reserved slot, ready to be initialized via UninitReservedMemory::init.
  • None — all slots are currently in use.

Trait Implementations§

Source§

impl<const MAX_ITEM_COUNT: usize, const MAX_ITEM_SIZE: usize> Default for Arena<MAX_ITEM_COUNT, MAX_ITEM_SIZE>

Source§

fn default() -> Self

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

Auto Trait Implementations§

§

impl<const MAX_ITEM_COUNT: usize, const MAX_ITEM_SIZE: usize> Freeze for Arena<MAX_ITEM_COUNT, MAX_ITEM_SIZE>

§

impl<const MAX_ITEM_COUNT: usize, const MAX_ITEM_SIZE: usize> !RefUnwindSafe for Arena<MAX_ITEM_COUNT, MAX_ITEM_SIZE>

§

impl<const MAX_ITEM_COUNT: usize, const MAX_ITEM_SIZE: usize> !Send for Arena<MAX_ITEM_COUNT, MAX_ITEM_SIZE>

§

impl<const MAX_ITEM_COUNT: usize, const MAX_ITEM_SIZE: usize> !Sync for Arena<MAX_ITEM_COUNT, MAX_ITEM_SIZE>

§

impl<const MAX_ITEM_COUNT: usize, const MAX_ITEM_SIZE: usize> Unpin for Arena<MAX_ITEM_COUNT, MAX_ITEM_SIZE>

§

impl<const MAX_ITEM_COUNT: usize, const MAX_ITEM_SIZE: usize> UnsafeUnpin for Arena<MAX_ITEM_COUNT, MAX_ITEM_SIZE>

§

impl<const MAX_ITEM_COUNT: usize, const MAX_ITEM_SIZE: usize> !UnwindSafe for Arena<MAX_ITEM_COUNT, MAX_ITEM_SIZE>

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.