Skip to main content

Arena

Struct Arena 

Source
pub struct Arena<T> { /* private fields */ }
Expand description

Fixed-capacity generational arena.

A pre-allocated, generational arena allocator that provides O(1) insert/remove with use-after-free detection. All memory is allocated upfront - zero heap activity during audio processing.

§Features

  • O(1) insert/remove: Constant-time operations
  • Generational indices: Prevents use-after-free bugs
  • Pre-allocated: No runtime allocation
  • Real-time safe: No locks, no allocation, bounded time

§Example

use aether_core::arena::Arena;

let mut arena: Arena<String> = Arena::with_capacity(100);

// Insert values
let id1 = arena.insert("Hello".to_string()).unwrap();
let id2 = arena.insert("World".to_string()).unwrap();

// Access values
assert_eq!(arena.get(id1).unwrap(), "Hello");
assert_eq!(arena.get(id2).unwrap(), "World");

// Remove and reuse slots
arena.remove(id1);
let id3 = arena.insert("Rust".to_string()).unwrap();

// Old ID is invalid, new ID is valid
assert!(arena.get(id1).is_none());
assert_eq!(arena.get(id3).unwrap(), "Rust");

§Capacity

The arena has a fixed capacity set at creation. When full, insert() returns None. Removed slots are recycled via a free list.

§Use Case

Perfect for managing DSP nodes in an audio graph where:

  • Nodes are added/removed dynamically
  • Need to prevent dangling references
  • Must avoid runtime allocation
  • Require O(1) operations

§See Also

  • NodeId - Generational index type

Implementations§

Source§

impl<T> Arena<T>

Source

pub fn with_capacity(capacity: usize) -> Self

Allocate a new arena with capacity pre-reserved slots.

All memory is allocated upfront. The arena can hold up to capacity items simultaneously. Removed slots are recycled.

§Arguments
  • capacity - Maximum number of items the arena can hold
§Example
use aether_core::arena::Arena;

let arena: Arena<i32> = Arena::with_capacity(1000);
assert_eq!(arena.len(), 0);
assert!(arena.is_empty());
§Performance
  • Time: O(capacity) - initializes free list
  • Space: O(capacity) - pre-allocates all slots
  • No further allocation after construction
Source

pub fn insert(&mut self, value: T) -> Option<NodeId>

Insert a value, returning its generational id.

Allocates a slot from the free list and stores the value. Returns a NodeId that can be used to access the value later.

§Arguments
  • value - Value to insert
§Returns
  • Some(NodeId) - Generational ID for the inserted value
  • None - Arena is full (all slots occupied)
§Example
use aether_core::arena::Arena;

let mut arena: Arena<String> = Arena::with_capacity(10);

let id = arena.insert("Hello".to_string()).unwrap();
assert_eq!(arena.get(id).unwrap(), "Hello");
assert_eq!(arena.len(), 1);
§Capacity Exhaustion
use aether_core::arena::Arena;

let mut arena: Arena<i32> = Arena::with_capacity(2);

let id1 = arena.insert(1).unwrap();
let id2 = arena.insert(2).unwrap();
let id3 = arena.insert(3); // None - arena is full

assert!(id3.is_none());

// Remove a slot to make space
arena.remove(id1);
let id4 = arena.insert(4).unwrap(); // Now succeeds
§Performance
  • Time: O(1)
  • Space: O(0) - no allocation
  • Real-time safe
Source

pub fn remove(&mut self, id: NodeId) -> Option<T>

Remove a value by id. Returns the value if the id was valid.

Removes the value from the arena, increments the slot’s generation counter (invalidating all existing IDs), and returns the slot to the free list for reuse.

§Arguments
  • id - Generational ID of the value to remove
§Returns
  • Some(T) - The removed value (if ID was valid)
  • None - ID was invalid (wrong generation or already removed)
§Example
use aether_core::arena::Arena;

let mut arena: Arena<i32> = Arena::with_capacity(10);

let id = arena.insert(42).unwrap();
assert_eq!(arena.len(), 1);

let value = arena.remove(id).unwrap();
assert_eq!(value, 42);
assert_eq!(arena.len(), 0);

// ID is now invalid
assert!(arena.get(id).is_none());
assert!(arena.remove(id).is_none());
§Generation Bump
use aether_core::arena::Arena;

let mut arena: Arena<i32> = Arena::with_capacity(10);

let id1 = arena.insert(1).unwrap();
let gen1 = id1.generation;

arena.remove(id1);

let id2 = arena.insert(2).unwrap();
let gen2 = id2.generation;

// Same slot, different generation
assert_eq!(id1.index, id2.index);
assert_eq!(gen2, gen1 + 1);
§Performance
  • Time: O(1)
  • Space: O(0) - no allocation
  • Real-time safe
Source

pub fn get(&self, id: NodeId) -> Option<&T>

Get a shared reference. Returns None for stale ids.

Returns a reference to the value if the ID is valid (correct generation and slot is occupied). Returns None if the ID is stale or invalid.

§Arguments
  • id - Generational ID to look up
§Returns
  • Some(&T) - Reference to the value (if ID is valid)
  • None - ID is invalid or stale
§Example
use aether_core::arena::Arena;

let mut arena: Arena<String> = Arena::with_capacity(10);

let id = arena.insert("Hello".to_string()).unwrap();

// Valid ID
assert_eq!(arena.get(id).unwrap(), "Hello");

arena.remove(id);

// Stale ID
assert!(arena.get(id).is_none());
§Performance
  • Time: O(1)
  • Inlined for zero call overhead
  • Real-time safe
Source

pub fn get_mut(&mut self, id: NodeId) -> Option<&mut T>

Get a mutable reference. Returns None for stale ids.

Returns a mutable reference to the value if the ID is valid. Returns None if the ID is stale or invalid.

§Arguments
  • id - Generational ID to look up
§Returns
  • Some(&mut T) - Mutable reference to the value (if ID is valid)
  • None - ID is invalid or stale
§Example
use aether_core::arena::Arena;

let mut arena: Arena<i32> = Arena::with_capacity(10);

let id = arena.insert(42).unwrap();

// Modify the value
if let Some(value) = arena.get_mut(id) {
    *value = 99;
}

assert_eq!(*arena.get(id).unwrap(), 99);
§Performance
  • Time: O(1)
  • Inlined for zero call overhead
  • Real-time safe
Source

pub fn len(&self) -> usize

Source

pub fn is_empty(&self) -> bool

Auto Trait Implementations§

§

impl<T> Freeze for Arena<T>

§

impl<T> RefUnwindSafe for Arena<T>
where T: RefUnwindSafe,

§

impl<T> Send for Arena<T>
where T: Send,

§

impl<T> Sync for Arena<T>
where T: Sync,

§

impl<T> Unpin for Arena<T>
where T: Unpin,

§

impl<T> UnsafeUnpin for Arena<T>

§

impl<T> UnwindSafe for Arena<T>
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, 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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
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.