pub struct BoundedSlab<T> { /* private fields */ }Expand description
Fixed-capacity slab allocator.
Uses pointer-based freelist for O(1) allocation.
§Drop Behavior
Dropping a Slab does not drop values in occupied slots. SlotCell is
a union, so the compiler cannot know which slots contain live values. The
caller must free all outstanding RawSlot handles before dropping the
slab, or the values will be leaked.
This is acceptable for the primary use case (TLS via thread_local!) where
thread exit leaks all TLS storage anyway.
§Const Construction
Supports const construction via new() followed by
runtime initialization via init(). This enables use with
thread_local! using the const { } block syntax for zero-overhead TLS access.
thread_local! {
static SLAB: Slab<MyType> = const { Slab::new() };
}
// Later, at runtime:
SLAB.with(|s| s.init(1024));For direct usage, prefer with_capacity().
Implementations§
Source§impl<T> Slab<T>
impl<T> Slab<T>
Sourcepub const fn new() -> Slab<T>
pub const fn new() -> Slab<T>
Creates an empty, uninitialized slab.
This is a const function that performs no allocation. Call init()
to allocate storage before use.
For direct usage, prefer with_capacity().
§Example
// For use with thread_local! const initialization
thread_local! {
static SLAB: Slab<u64> = const { Slab::new() };
}Sourcepub fn with_capacity(capacity: usize) -> Slab<T>
pub fn with_capacity(capacity: usize) -> Slab<T>
Sourcepub fn init(&self, capacity: usize)
pub fn init(&self, capacity: usize)
Initializes the slab with the given capacity.
This allocates slot storage and builds the freelist. Must be called exactly once before any allocations.
§Panics
- Panics if the slab is already initialized (capacity > 0)
- Panics if capacity is zero
Sourcepub fn is_initialized(&self) -> bool
pub fn is_initialized(&self) -> bool
Returns true if the slab has been initialized.
Sourcepub fn claim(&self) -> Option<Claim<'_, T>>
pub fn claim(&self) -> Option<Claim<'_, T>>
Claims a slot from the freelist without writing a value.
Returns None if the slab is full. The returned Claim must be
consumed via Claim::write() to complete the allocation.
This two-phase allocation enables placement new optimization: the value can be constructed directly into the slot memory.
§Example
use nexus_slab::bounded::Slab;
let slab = Slab::with_capacity(10);
if let Some(claim) = slab.claim() {
let slot = claim.write(42u64);
assert_eq!(*slot, 42);
// SAFETY: slot was allocated from this slab
unsafe { slab.free(slot) };
}Sourcepub fn try_alloc(&self, value: T) -> Result<RawSlot<T>, Full<T>>
pub fn try_alloc(&self, value: T) -> Result<RawSlot<T>, Full<T>>
Tries to allocate a slot and write the value.
Returns Err(Full(value)) if the slab is at capacity.
Source§impl<const N: usize> Slab<AlignedBytes<N>>
impl<const N: usize> Slab<AlignedBytes<N>>
Sourcepub fn try_insert<T>(&self, value: T) -> Result<Slot<T>, T>
pub fn try_insert<T>(&self, value: T) -> Result<Slot<T>, T>
Sourcepub unsafe fn remove<T>(&self, slot: Slot<T>)where
T: ?Sized,
pub unsafe fn remove<T>(&self, slot: Slot<T>)where
T: ?Sized,
Drops the value and frees the slot.
Handles both thin and fat pointers: extracts the data pointer for
freeing regardless of whether T is Sized or dyn Trait.
§Safety
slotmust have been allocated from this slab
Sourcepub unsafe fn take_value<T>(&self, slot: Slot<T>) -> T
pub unsafe fn take_value<T>(&self, slot: Slot<T>) -> T
Extracts the value and frees the slot (Sized only).
§Safety
slotmust have been allocated from this slab