my_ecs/ds/vec/
vec_pool.rs

1/// Simple vector pool.
2///
3/// The pool holds used vectors while keeping their capacities to avoid frequent
4/// memory allocation.
5#[derive(Debug)]
6pub struct SimpleVecPool<T> {
7    bufs: Vec<Vec<T>>,
8    free: Vec<usize>,
9}
10
11impl<T> SimpleVecPool<T> {
12    /// Creates a new empty vector pool.
13    ///
14    /// # Examples
15    ///
16    /// ```
17    /// use my_ecs::ds::SimpleVecPool;
18    ///
19    /// let mut pool = SimpleVecPool::<i32>::new();
20    /// ```
21    pub const fn new() -> Self {
22        Self {
23            bufs: Vec::new(),
24            free: Vec::new(),
25        }
26    }
27
28    /// Returns an index to a vector of the pool.
29    ///
30    /// The pool prefers to reuse vector, therefore caller will receive an index
31    /// to a used vector if the pool contains used vectors. In that case, the
32    /// vector is completed cleared while keeping its capacity. If the pool
33    /// doesn't have any used vectors in it, a new vector is created.
34    ///
35    /// # Examples
36    ///
37    /// ```
38    /// use my_ecs::ds::SimpleVecPool;
39    ///
40    /// let mut pool = SimpleVecPool::<i32>::new();
41    ///
42    /// let index = pool.request();
43    /// let v = pool.get(index);
44    /// v.reserve(10);
45    /// drop(v);
46    ///
47    /// pool.release(index);
48    /// let index = pool.request(); // pool will return the used vector
49    /// let v = pool.get(index);
50    /// assert!(v.is_empty());
51    /// assert!(v.capacity() >= 10);
52    /// ```
53    pub fn request(&mut self) -> usize {
54        if let Some(index) = self.free.pop() {
55            self.bufs[index].clear();
56            index
57        } else {
58            self.bufs.push(Vec::new());
59            self.bufs.len() - 1
60        }
61    }
62
63    /// Lets the pool know the end of use of a vector.
64    ///
65    /// # Examples
66    ///
67    /// ```
68    /// use my_ecs::ds::SimpleVecPool;
69    ///
70    /// let mut pool = SimpleVecPool::<i32>::new();
71    /// let index0 = pool.request();
72    /// pool.release(index0);
73    ///
74    /// let index1 = pool.request(); // pool will return the used vector
75    /// assert_eq!(index0, index1);
76    /// ```
77    pub fn release(&mut self, index: usize) {
78        // Takes O(n).
79        debug_assert!(!self.free.contains(&index));
80
81        self.free.push(index);
82    }
83
84    /// Returns a mutable reference to a vector at the given index.
85    ///
86    /// # Examples
87    ///
88    /// ```
89    /// use my_ecs::ds::SimpleVecPool;
90    ///
91    /// let mut pool = SimpleVecPool::new();
92    /// let index = pool.request();
93    /// let v = pool.get(index);
94    /// v.push(0);
95    /// ```
96    pub fn get(&mut self, index: usize) -> &mut Vec<T> {
97        &mut self.bufs[index]
98    }
99}
100
101impl<T> Default for SimpleVecPool<T> {
102    fn default() -> Self {
103        Self::new()
104    }
105}