Skip to main content

moirai_core/memory/
pool.rs

1//! Capacity-bounded object pool parameterizing the crate's single
2//! slot-freelist implementation, [`crate::pool::LockFreeStack`].
3
4use crate::pool::LockFreeStack;
5
6/// Memory pool for reducing allocation overhead.
7///
8/// A capacity-bounded, lock-free object pool: [`Self::deallocate`] stores up to
9/// `max_size` objects for reuse and [`Self::allocate`] pops a stored object or
10/// falls back to `T::default()`. The freelist mechanics live in
11/// [`LockFreeStack`]; this type only adds the pool vocabulary
12/// (allocate/deallocate) over the stack's fixed slot capacity.
13pub struct MemoryPool<T> {
14    stack: LockFreeStack<T>,
15}
16
17impl<T> MemoryPool<T> {
18    /// Create a new memory pool retaining at most `max_size` objects.
19    #[must_use]
20    pub fn new(max_size: usize) -> Self {
21        Self {
22            stack: LockFreeStack::with_capacity(max_size),
23        }
24    }
25
26    /// Allocate an object from the pool or create new if pool is empty
27    pub fn allocate(&self) -> T
28    where
29        T: Default,
30    {
31        self.stack.pop().unwrap_or_default()
32    }
33
34    /// Return an object to the pool for reuse.
35    ///
36    /// When the pool already holds `max_size` objects the item is dropped;
37    /// this is the pool's documented retention cap, not an error condition.
38    pub fn deallocate(&self, item: T) {
39        if let Err(item) = self.stack.push(item) {
40            drop(item); // pool at capacity: intentional retention-cap drop
41        }
42    }
43
44    /// Get current pool size
45    pub fn size(&self) -> usize {
46        self.stack.len()
47    }
48}