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>
impl<T> Arena<T>
Sourcepub fn with_capacity(capacity: usize) -> Self
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
Sourcepub fn insert(&mut self, value: T) -> Option<NodeId>
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 valueNone- 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
Sourcepub fn remove(&mut self, id: NodeId) -> Option<T>
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
Sourcepub fn get(&self, id: NodeId) -> Option<&T>
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
Sourcepub fn get_mut(&mut self, id: NodeId) -> Option<&mut T>
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
pub fn len(&self) -> usize
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> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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