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}