Skip to main content

BoundedSlab

Struct BoundedSlab 

Source
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>

Source

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() };
}
Source

pub fn with_capacity(capacity: usize) -> Slab<T>

Creates a new slab with the given capacity.

§Panics

Panics if capacity is zero.

Source

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
Source

pub fn is_initialized(&self) -> bool

Returns true if the slab has been initialized.

Source

pub fn capacity(&self) -> usize

Returns the capacity.

Source

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) };
}
Source

pub fn alloc(&self, value: T) -> RawSlot<T>

Allocates a slot and writes the value.

§Panics

Panics if the slab is full.

Source

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

pub unsafe fn free(&self, slot: RawSlot<T>)

Frees a slot, dropping the value and returning storage to the freelist.

§Safety
  • slot must have been allocated from this slab
  • No references to the slot’s value may exist
Source

pub unsafe fn take(&self, slot: RawSlot<T>) -> T

Frees a slot and returns the value without dropping it.

§Safety
  • slot must have been allocated from this slab
  • No references to the slot’s value may exist
Source§

impl<const N: usize> Slab<AlignedBytes<N>>

Source

pub fn try_insert<T>(&self, value: T) -> Result<Slot<T>, T>

Inserts a value into the slab, returning a Slot handle.

Returns Err(value) if the slab is full.

§Compile-Time Checks

Fails to compile if T is too large or too aligned for the slot.

Source

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
  • slot must have been allocated from this slab
Source

pub unsafe fn take_value<T>(&self, slot: Slot<T>) -> T

Extracts the value and frees the slot (Sized only).

§Safety
  • slot must have been allocated from this slab
Source

pub unsafe fn reclaim<T>(&self, slot: Slot<T>)
where T: ?Sized,

Frees the slot without dropping the value.

Use when the value has already been moved out or dropped.

§Safety
  • slot must have been allocated from this slab
  • The value must already be dropped or moved out

Trait Implementations§

Source§

impl<T> BoundedStore for Slab<T>

Source§

fn try_alloc(&self, value: T) -> Result<RawSlot<T>, Full<T>>

Attempts to allocate a slot with the given value. Read more
Source§

impl<T> Debug for Slab<T>

Source§

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

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

impl<T> Default for Slab<T>

Source§

fn default() -> Slab<T>

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

impl<T> SlabStore for Slab<T>

Source§

type Item = T

The type stored in each slot.
Source§

fn alloc(&self, value: T) -> RawSlot<T>

Allocates a slot with the given value. Read more
Source§

unsafe fn free(&self, slot: RawSlot<T>)

Drops the value and returns the slot to the freelist. Read more
Source§

unsafe fn take(&self, slot: RawSlot<T>) -> T

Moves the value out and returns the slot to the freelist. Read more
Source§

unsafe fn free_ptr(&self, ptr: *mut SlotCell<T>)

Returns a slot to the freelist by raw pointer. Read more

Auto Trait Implementations§

§

impl<T> !Freeze for Slab<T>

§

impl<T> !RefUnwindSafe for Slab<T>

§

impl<T> !Send for Slab<T>

§

impl<T> !Sync for Slab<T>

§

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

§

impl<T> UnsafeUnpin for Slab<T>

§

impl<T> UnwindSafe for Slab<T>

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.