A very simple, uniformly-typed slab arena that supports deallocation and reusing deallocated entries' space.
The free list of vacant entries in the slab are stored inline in the slab's existing storage.
Example
use ;
let mut slab = new;
// Insert some values into the slab.
let rza = slab.alloc;
let gza = slab.alloc;
let bill = slab.alloc;
// Allocated elements can be accessed infallibly via indexing (and missing and
// deallocated entries will panic).
assert_eq!;
// Alternatively, the `get` and `get_mut` methods provide fallible lookup.
if let Some = slab.get
if let Some = slab.get_mut
// We can remove values from the slab.
slab.dealloc;
// Allocate a new entry.
let bill = slab.alloc;
Using Ids with the Wrong Slab
Slab does NOT check that Ids used to access previously-allocated values
came from the current Slab instance (as opposed to a different Slab
instance). Using Ids from a different Slab is safe, but will yield an
unrelated value, if any at all.
If you desire checking that an Id came from the correct Slab instance,
it should be easy to layer that functionality on top of this crate by
wrapping Slab and Id in types that additionally maintain a slab instance
identifier.
The ABA Problem
This Slab type does NOT protect against ABA bugs, such as the following
sequence:
-
Value
Ais allocated into the slab, yielding idi. -
Ais deallocated, and soi's associated entry is added to the slab's free list. -
Value
Bis allocated into the slab, reusingi's associated entry, yielding idi. -
The "original" id
iis used to access the arena, expecting the deallocated valueA, but getting the new valueB.
That is, it does not detect and prevent against the memory-safe version of use-after-free bugs.
If you need to protect against ABA bugs, it should be easy to layer that
functionality on top of this crate by wrapping Slab with something like
the following: