pub struct Pool<T> { /* private fields */ }Expand description
A slotmap-style arena: values in, Handles out.
Insertion recycles free slots through a free list, so live values stay
densely packed near the front of the backing Vec under steady-state
churn. Every removal bumps the slot’s generation, so handles issued before
the removal stop resolving.
§Generation exhaustion
Generations are 32-bit and never wrap. A slot that has been recycled
u32::MAX - 1 times is retired: its storage is dropped, the slot is
removed from the free list, and it is never handed out again. Wrapping would
silently resurrect a >4-billion-removals-old handle as a valid alias for an
unrelated value — a bug that would surface as impossible-looking aliasing
weeks into a server’s uptime. Retiring instead costs one dead Vec entry
(a few bytes) per exhausted slot, and only after ~4.3e9 reuses of that one
slot: at 60 Hz, recycling the same slot every tick, that is over two years
of continuous churn. See Pool::retired_slots to observe it.
§Safety
This module contains no unsafe. The Vec<Slot<T>> + enum payload costs
one discriminant per slot versus a hand-rolled MaybeUninit arena; clarity
wins at this layer, and the pool is not in any inner loop that measures.
Implementations§
Source§impl<T> Pool<T>
impl<T> Pool<T>
Sourcepub fn with_capacity(capacity: usize) -> Self
pub fn with_capacity(capacity: usize) -> Self
Creates an empty pool with room for capacity slots.
Sourcepub const fn retired_slots(&self) -> usize
pub const fn retired_slots(&self) -> usize
Number of slots permanently withdrawn by generation exhaustion.
Expected to be zero forever; a non-zero value in a long-running server is worth a metric, not an alarm.
Sourcepub fn insert(&mut self, value: T) -> Handle<T>
pub fn insert(&mut self, value: T) -> Handle<T>
Inserts value and returns a handle to it.
§Panics
If the pool would exceed u32::MAX + 1 slots — the index is 32-bit by
design, and a pool that large is a leak, not a workload.
Sourcepub fn get(&self, handle: Handle<T>) -> Option<&T>
pub fn get(&self, handle: Handle<T>) -> Option<&T>
Borrows the value handle names, or None if the handle is stale.
Sourcepub fn get_mut(&mut self, handle: Handle<T>) -> Option<&mut T>
pub fn get_mut(&mut self, handle: Handle<T>) -> Option<&mut T>
Mutably borrows the value handle names, or None if the handle is
stale.
Sourcepub fn remove(&mut self, handle: Handle<T>) -> Option<T>
pub fn remove(&mut self, handle: Handle<T>) -> Option<T>
Removes and returns the value handle names, invalidating every handle
to that slot.
Returns None (and changes nothing) if the handle is already stale.
Sourcepub fn clear(&mut self)
pub fn clear(&mut self)
Removes every value, invalidating all outstanding handles.
Slot storage is kept for reuse; generations continue from where they were, so handles issued before the clear stay dead.
Trait Implementations§
Source§impl<T> Debug for Pool<T>
Deliberately does not print the values: a pool is usually large, and this
impl must exist for every T, not just T: Debug.
impl<T> Debug for Pool<T>
Deliberately does not print the values: a pool is usually large, and this
impl must exist for every T, not just T: Debug.
Source§impl<T> Extend<T> for Pool<T>
impl<T> Extend<T> for Pool<T>
Source§fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I)
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I)
Source§fn extend_one(&mut self, item: T)
fn extend_one(&mut self, item: T)
extend_one)Source§fn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one)