pub struct ObjectPool<T> { /* private fields */ }Expand description
A reusable object pool with a free-list that preserves memory across release/acquire cycles.
The pool keeps two disjoint collections of T: the free list of values
the pool owns and is ready to hand out again, and the count of values
currently checked out and tracked as active. Releasing a value never
destroys it — the caller’s value is moved back onto the free list and
reused by the next acquire, so a per-frame spawn/despawn cycle stops
paying for Vec growth and reallocation.
§Checkout order
The free list is LIFO: ObjectPool::acquire pops the most recently
released value. The most recently used value is therefore the next one
handed out, which keeps a recycling workload on the hottest allocations
instead of sweeping a cold list.
§Why hand-written accessors
Lombok’s Data derive is intentionally not applied here, matching the
precedent set by Tween and
EngineCell: the derive does not propagate generic
bounds, so deriving on ObjectPool<T> would constrain T in ways the
pool must not constrain. The accessors below follow the same naming
contract as the Lombok-generated ones (get_* / get_mut_* / set_*).
Implementations§
Source§impl<T> ObjectPool<T>
Implements construction, checkout, return, and introspection for
ObjectPool.
impl<T> ObjectPool<T>
Implements construction, checkout, return, and introspection for
ObjectPool.
Checkout is LIFO on the free list (see ObjectPool for the rationale),
and every successful acquire pairs with exactly one release, so the
active count returns to zero once all outstanding values are back.
Sourcepub fn new(initial: Vec<T>) -> ObjectPool<T>
pub fn new(initial: Vec<T>) -> ObjectPool<T>
Sourcepub fn empty() -> ObjectPool<T>
pub fn empty() -> ObjectPool<T>
Constructs an empty pool.
The free list is reserved to [POOL_DEFAULT_PREWARM] so a default
pool starts with a pre-sized free list; a prewarm size of zero
reserves nothing and the first release grows the list.
§Returns
ObjectPool<T>- The new pool.
Sourcepub fn get_active(&self) -> usize
pub fn get_active(&self) -> usize
Returns the number of values currently checked out of the pool.
Named get_active rather than active so it does not collide with
the field of the same name.
§Returns
usize- The active count.
Sourcepub fn set_active(&mut self, active: usize)
pub fn set_active(&mut self, active: usize)
Sets the number of tracked active values.
Only for pool owners that track checkouts out of band; acquire and
release maintain the count themselves.
§Arguments
usize- The new active count.
Sourcepub fn get_free(&self) -> &Vec<T>
pub fn get_free(&self) -> &Vec<T>
Returns the values the pool owns and can hand out.
§Returns
&Vec<T>- The free list, most-recently-released first.
Sourcepub fn get_mut_free(&mut self) -> &mut Vec<T>
pub fn get_mut_free(&mut self) -> &mut Vec<T>
Returns a mutable reference to the free list.
§Returns
&mut Vec<T>- The free list, for bulk seeding before first use.
Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Returns the total number of values the pool tracks, active plus free.
This is the pool’s high-water mark: it grows only when a factory builds a value the pool could not serve, and never shrinks on a release.
§Returns
usize- The tracked value count.
Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns whether the pool tracks no values at all.
§Returns
bool- True when both the active count and the free list are empty.
Sourcepub fn acquire(&mut self) -> Option<T>
pub fn acquire(&mut self) -> Option<T>
Checks a pooled value out, or reports that the free list is empty.
This is the factory-free form: it never builds a new value, so it
reports None on a miss. Use Self::acquire_with when the pool
should grow on demand.
§Returns
Option<T>- A recycled value, orNoneif none was available.
Sourcepub fn acquire_with<F>(&mut self, make: F) -> Twhere
F: FnMut() -> T,
pub fn acquire_with<F>(&mut self, make: F) -> Twhere
F: FnMut() -> T,
Checks a pooled value out, calling make only when the free list is
empty.
A recycled value is returned verbatim; the factory runs at most once per acquire and its result is handed to the caller, so the pool never duplicates the value’s allocation.
§Arguments
F- Factory building a fresh value on a miss.
§Returns
T- The recycled value, or a freshly built one.
Sourcepub fn release(&mut self, value: T)
pub fn release(&mut self, value: T)
Returns a value to the free list without destroying it.
The value is moved onto the free list, so the allocation behind it survives for the next acquire. The active count only decrements while a checkout is outstanding, which keeps the count honest even when a caller returns a value it never acquired.
§Arguments
T- The value to make available again.
Sourcepub fn prewarm<F>(&mut self, count: usize, make: F) -> usizewhere
F: FnMut() -> T,
pub fn prewarm<F>(&mut self, count: usize, make: F) -> usizewhere
F: FnMut() -> T,
Builds count values up front and returns how many are available.
Prewarming moves the factory cost off the first frames of a spawn
loop; the pool then serves that many acquires without calling make
again.
§Arguments
usize- How many values to build.F- Factory building each new value.
§Returns
usize- The number of values now available on the free list.
Trait Implementations§
Source§impl<T> Debug for ObjectPool<T>
Implements Debug for ObjectPool showing counts rather than values.
impl<T> Debug for ObjectPool<T>
Implements Debug for ObjectPool showing counts rather than values.
T is deliberately not required to implement Debug, so a pool of
closure or handle types still prints usefully.
Source§impl<T> Default for ObjectPool<T>
Implements Default for ObjectPool as a new empty pool.
impl<T> Default for ObjectPool<T>
Implements Default for ObjectPool as a new empty pool.
Source§fn default() -> ObjectPool<T>
fn default() -> ObjectPool<T>
Constructs a default ObjectPool value.
§Returns
ObjectPool<T>- A default-constructed instance with the documented initial state.