1use std::mem;
17use std::slice;
18use std::iter::{Enumerate, FilterMap};
19use std::ops::{Index, IndexMut};
20use std::vec::Vec;
21
22use serde::{Serialize, Deserialize};
23
24#[derive(Serialize, Deserialize)]
26pub enum PoolEntry<T> {
27 FreeListEnd,
28 FreeListPtr {
29 next_free: usize,
30 },
31 Occupied(T)
32}
33
34#[derive(Serialize, Deserialize)]
37pub struct Pool<T> {
38 len: usize,
39 free_list: Option<usize>,
40 entries: Vec<PoolEntry<T>>,
41}
42
43impl<T> Pool<T> {
44 pub fn new() -> Self {
46 Pool {
47 len: 0,
48 free_list: None,
49 entries: Vec::new(),
50 }
51 }
52
53 pub fn with_capacity(cap: usize) -> Self {
55 Pool {
56 len: 0,
57 free_list: None,
58 entries: Vec::with_capacity(cap),
59 }
60 }
61
62 pub fn empty(&self) -> bool {
64 self.len == 0
65 }
66
67 pub fn len(&self) -> usize {
69 self.len
70 }
71
72 pub fn clear(&mut self) {
74 self.len = 0;
75 self.free_list = None;
76 self.entries.clear();
77 }
78
79 pub fn push(&mut self, item: T) -> usize {
82 self.len += 1;
83 if let Some(free_item) = self.free_list {
84 self.free_list = match self.entries[free_item] {
85 PoolEntry::FreeListEnd => None,
86 PoolEntry::FreeListPtr{ next_free } => Some(next_free),
87 _ => unreachable!(),
88 };
89 self.entries[free_item] = PoolEntry::Occupied(item);
90 free_item
91 } else {
92 let i = self.entries.len();
93 self.entries.push(PoolEntry::Occupied(item));
94 i
95 }
96 }
97
98 pub fn remove(&mut self, i: usize) -> T {
101 let new_entry = if let Some(free_item) = self.free_list {
102 PoolEntry::FreeListPtr{ next_free: free_item }
103 } else {
104 PoolEntry::FreeListEnd
105 };
106 self.free_list = Some(i);
107 if let PoolEntry::Occupied(item) = mem::replace(&mut self.entries[i], new_entry) {
108 self.len -= 1;
109 item
110 } else {
111 panic!("index {} is not occupied", i);
112 }
113 }
114
115 pub fn next_free(&self) -> Option<usize> {
117 if let Some(free) = self.free_list {
118 Some(free)
119 } else {
120 None
121 }
122 }
123
124 pub fn iter<'a>(&'a self) -> impl Iterator<Item=(usize, &'a T)> {
125 self.into_iter()
126 }
127
128 pub fn iter_mut<'a>(&'a mut self) -> impl Iterator<Item=(usize, &'a mut T)> {
129 self.into_iter()
130 }
131
132 pub fn get<'a>(&'a self, i: usize) -> Option<&'a T> {
135 if let Some(PoolEntry::Occupied(ref item)) = self.entries.get(i) {
136 Some(&item)
137 } else {
138 None
139 }
140 }
141
142 pub fn get_mut<'a>(&'a mut self, i: usize) -> Option<&'a mut T> {
145 if let Some(PoolEntry::Occupied(ref mut item)) = self.entries.get_mut(i) {
146 Some(item)
147 } else {
148 None
149 }
150 }
151}
152
153impl<T> Index<usize> for Pool<T> {
154 type Output = T;
155
156 fn index(&self, i: usize) -> &T {
157 if let PoolEntry::Occupied(ref item) = self.entries[i] {
158 item
159 } else {
160 panic!("index {} is not occupied", i)
161 }
162 }
163}
164
165impl<T> IndexMut<usize> for Pool<T> {
166 fn index_mut(&mut self, i: usize) -> &mut T {
167 if let PoolEntry::Occupied(ref mut item) = self.entries[i] {
168 item
169 } else {
170 panic!("index {} is not occupied", i)
171 }
172 }
173}
174
175impl<T> Clone for PoolEntry<T>
176where
177 T: Clone
178{
179 fn clone(&self) -> Self {
180 use self::PoolEntry::*;
181 match self {
182 &FreeListEnd => FreeListEnd,
183 &FreeListPtr{ next_free } => FreeListPtr{ next_free },
184 &Occupied(ref item) => Occupied(item.clone()),
185 }
186 }
187}
188
189impl<T> Clone for Pool<T>
190where
191 T: Clone
192{
193 fn clone(&self) -> Self {
194 Pool {
195 len: self.len,
196 free_list: self.free_list,
197 entries: self.entries.clone(),
198 }
199 }
200}
201
202impl<L, T> From<L> for Pool<T>
203where
204 L: IntoIterator<Item = T>
205{
206 fn from(iter: L) -> Pool<T> {
207 let mut pool = Pool::new();
208 for item in iter.into_iter() {
209 pool.push(item);
210 }
211 pool
212 }
213}
214
215fn filter_pool<'a, T>((i, item): (usize, &'a PoolEntry<T>)) -> Option<(usize, &'a T)> {
216 if let &PoolEntry::Occupied(ref item) = item {
217 Some((i, item))
218 } else {
219 None
220 }
221}
222
223impl<'a, T> IntoIterator for &'a Pool<T> {
224 type Item = (usize, &'a T);
225 type IntoIter = FilterMap<Enumerate<slice::Iter<'a, PoolEntry<T>>>, fn((usize, &PoolEntry<T>)) -> Option<(usize, &T)>>;
226
227 fn into_iter(self) -> Self::IntoIter {
228 self.entries.iter().enumerate().filter_map(filter_pool)
229 }
230}
231
232fn filter_pool_mut<'a, T>((i, item): (usize, &'a mut PoolEntry<T>)) -> Option<(usize, &'a mut T)> {
233 if let &mut PoolEntry::Occupied(ref mut item) = item {
234 Some((i, item))
235 } else {
236 None
237 }
238}
239
240impl<'a, T> IntoIterator for &'a mut Pool<T> {
241 type Item = (usize, &'a mut T);
242 type IntoIter = FilterMap<Enumerate<slice::IterMut<'a, PoolEntry<T>>>, fn((usize, &mut PoolEntry<T>)) -> Option<(usize, &mut T)>>;
243
244 fn into_iter(self) -> Self::IntoIter {
245 self.entries.iter_mut().enumerate().filter_map(filter_pool_mut)
246 }
247}
248
249#[cfg(test)]
250mod tests {
251 mod pool {
252 use crate::pool::*;
253
254 #[test]
255 fn test_manual_code() {
256 let mut pool: Pool<usize> = Pool::new();
257
258 let id0 = pool.push(0);
259 let id1 = pool.push(1);
260 let id2 = pool.push(2);
261 let id3 = pool.push(3);
262
263 assert_eq!(id0, 0);
264 assert_eq!(id3, 3);
265
266 pool.remove(id1);
267 pool.remove(id2);
268
269 assert_eq!(pool[id0], 0);
270 assert_eq!(pool[id3], 3);
271
272 assert_eq!(pool.iter().map(|(_i, &u)|{u}).collect::<Vec<usize>>(), vec![0, 3]);
273 }
274
275 #[test]
276 fn test_pool() {
277 {
279 let mut pool: Pool<usize> = Pool::new();
280 for i in 0..8 {
281 pool.push(i);
282 }
283 let ids = [ 0, 1, 2, 3, 4, 5, 6, 7 ];
284 for (i, item) in pool.iter().enumerate() {
285 assert_eq!(*item.1, ids[i]);
286 }
287 for i in 0..4 {
289 pool.remove(i * 2);
290 }
291 let ids = [ 1, 3, 5, 7 ];
292 for (i, item) in pool.iter().enumerate() {
293 assert_eq!(*item.1, ids[i]);
294 }
295 {
296 let _removed = pool.remove(1);
297 let ids = [ 3, 5, 7 ];
298 for (i, item) in pool.iter().enumerate() {
299 assert_eq!(*item.1, ids[i]);
300 }
301 }
302 }
303 {
305 let mut pool: Pool<usize> = Pool::new();
306 for i in 0..16 {
307 pool.push(i);
308 }
309 let ids = [ 0, 1, 2, 3, 4, 5, 6, 7,
310 8, 9, 10, 11, 12, 13, 14, 15 ];
311 for (i, item) in pool.iter().enumerate() {
312 assert_eq!(*item.1, ids[i]);
313 }
314 for i in 0..8 {
316 pool.remove(i * 2);
317 }
318 let ids = [ 1, 3, 5, 7, 9, 11, 13, 15 ];
319 for (i, item) in pool.iter().enumerate() {
320 assert_eq!(*item.1, ids[i]);
321 }
322 {
323 let _removed = pool.remove(1);
324 let ids = [ 3, 5, 7, 9, 11, 13, 15 ];
325 for (i, item) in pool.iter().enumerate() {
326 assert_eq!(*item.1, ids[i]);
327 }
328 }
329 }
330 {
332
333 let mut pool: Pool<usize> = Pool::new();
334 for i in 0..16 {
335 pool.push(i);
336 }
337 let ids = [ 0, 1, 2, 3, 4, 5, 6, 7,
338 8, 9, 10, 11, 12, 13, 14, 15 ];
339 for (i, item) in pool.iter().enumerate() {
340 assert_eq!(*item.1, ids[i]);
341 }
342 for i in 0..8 {
343 pool.remove(i);
344 }
345 let ids = [ 8, 9, 10, 11, 12, 13, 14, 15 ];
346 for (i, item) in pool.iter().enumerate() {
347 assert_eq!(*item.1, ids[i]);
348 }
349 {
350 let _removed = pool.remove(8);
351 let ids = [ 9, 10, 11, 12, 13, 14, 15 ];
352 for (i, item) in pool.iter().enumerate() {
353 assert_eq!(*item.1, ids[i]);
354 }
355 }
356 }
357 {
359
360 let mut pool: Pool<usize> = Pool::new();
361 for i in 0..24 {
362 pool.push(i);
363 }
364 let ids = [ 0, 1, 2, 3, 4, 5, 6, 7,
365 8, 9, 10, 11, 12, 13, 14, 15,
366 16, 17, 18, 19, 20, 21, 22, 23 ];
367 for (i, item) in pool.iter().enumerate() {
368 assert_eq!(*item.1, ids[i]);
369 }
370 for i in 8..16 {
371 pool.remove(i);
372 }
373 let ids = [ 0, 1, 2, 3, 4, 5, 6, 7,
374 16, 17, 18, 19, 20, 21, 22, 23 ];
375 for (i, item) in pool.iter().enumerate() {
376 assert_eq!(*item.1, ids[i]);
377 }
378 {
379 let _removed1 = pool.remove(23);
380 let _removed2 = pool.remove(18);
381 let _removed2 = pool.remove(19);
382 let ids = [ 0, 1, 2, 3, 4, 5, 6, 7,
383 16, 17, 20, 21, 22 ];
384 for (i, item) in pool.iter().enumerate() {
385 assert_eq!(*item.1, ids[i]);
386 }
387 }
388 }
389 }
390 }
391}