pub struct UnboundedSlab<T> { /* private fields */ }Expand description
Growable slab allocator.
Uses independent chunks for growth — no copying when the slab grows.
§Safety Contract
Construction is unsafe because it opts you into manual memory
management. By creating a slab, you accept these invariants:
- Free from the correct slab. Passing a
Slotto a different slab’sfree()is undefined behavior — it corrupts the freelist. In debug builds, this is caught bydebug_assert!. - Free everything you allocate. Dropping the slab does NOT drop values in occupied slots. Unfreed slots leak silently.
- Single-threaded. The slab is
!Sendand!Sync.
§Why free() is safe
The safety contract is accepted once, at construction. After that:
Slotis move-only (noCopy, noClone) — double-free is prevented by the type system.free()consumes theSlot— the handle cannot be used after.- Cross-slab misuse is the only remaining hazard, and it was accepted as the caller’s responsibility at construction time.
Implementations§
Source§impl<T> Slab<T>
impl<T> Slab<T>
Sourcepub unsafe fn with_chunk_capacity(chunk_capacity: usize) -> Slab<T>
pub unsafe fn with_chunk_capacity(chunk_capacity: usize) -> Slab<T>
Creates a new slab with the given chunk capacity.
Chunks are allocated on-demand when slots are requested.
§Safety
See struct-level safety contract.
§Panics
Panics if chunk_capacity is zero.
Sourcepub fn chunk_capacity(&self) -> usize
pub fn chunk_capacity(&self) -> usize
Returns the chunk capacity.
Sourcepub fn chunk_count(&self) -> usize
pub fn chunk_count(&self) -> usize
Returns the number of allocated chunks.
Sourcepub fn reserve_chunks(&self, count: usize)
pub fn reserve_chunks(&self, count: usize)
Ensures at least count chunks are allocated.
No-op if the slab already has count or more chunks. Only allocates
the difference.
Sourcepub fn claim(&self) -> Claim<'_, T>
pub fn claim(&self) -> Claim<'_, T>
Claims a slot from the freelist without writing a value.
Always succeeds — grows the slab if needed. 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::unbounded::Slab;
// SAFETY: caller guarantees slab contract (see struct docs)
let slab = unsafe { Slab::with_chunk_capacity(16) };
let claim = slab.claim();
let slot = claim.write(42u64);
assert_eq!(*slot, 42);
slab.free(slot);Sourcepub fn alloc(&self, value: T) -> Slot<T>
pub fn alloc(&self, value: T) -> Slot<T>
Allocates a slot and writes the value.
Always succeeds — grows the slab if needed.