1use std::marker::PhantomData;
3use std::mem;
4use std::vec::Vec;
5use EntityRef;
6
7#[derive(Clone, Debug)]
62pub struct EntityList<T: EntityRef> {
63 index: u32,
64 unused: PhantomData<T>,
65}
66
67impl<T: EntityRef> Default for EntityList<T> {
69 fn default() -> Self {
70 Self {
71 index: 0,
72 unused: PhantomData,
73 }
74 }
75}
76
77#[derive(Clone, Debug)]
79pub struct ListPool<T: EntityRef> {
80 data: Vec<T>,
82
83 free: Vec<usize>,
85}
86
87type SizeClass = u8;
90
91fn sclass_size(sclass: SizeClass) -> usize {
94 4 << sclass
95}
96
97fn sclass_for_length(len: usize) -> SizeClass {
100 30 - (len as u32 | 3).leading_zeros() as SizeClass
101}
102
103fn is_sclass_min_length(len: usize) -> bool {
105 len > 3 && len.is_power_of_two()
106}
107
108impl<T: EntityRef> ListPool<T> {
109 pub fn new() -> Self {
111 Self {
112 data: Vec::new(),
113 free: Vec::new(),
114 }
115 }
116
117 pub fn clear(&mut self) {
124 self.data.clear();
125 self.free.clear();
126 }
127
128 fn len_of(&self, list: &EntityList<T>) -> Option<usize> {
130 let idx = list.index as usize;
131 self.data.get(idx.wrapping_sub(1)).map(|len| len.index())
138 }
139
140 fn alloc(&mut self, sclass: SizeClass) -> usize {
145 match self.free.get(sclass as usize).cloned() {
147 Some(head) if head > 0 => {
148 self.free[sclass as usize] = self.data[head].index();
153 head - 1
154 }
155 _ => {
156 let offset = self.data.len();
158 self.data.resize(offset + sclass_size(sclass), T::new(0));
161 offset
162 }
163 }
164 }
165
166 fn free(&mut self, block: usize, sclass: SizeClass) {
170 let sclass = sclass as usize;
171
172 if self.free.len() <= sclass {
174 self.free.resize(sclass + 1, 0);
175 }
176
177 self.data[block] = T::new(0);
179 self.data[block + 1] = T::new(self.free[sclass]);
181 self.free[sclass] = block + 1
182 }
183
184 fn mut_slices(&mut self, block0: usize, block1: usize) -> (&mut [T], &mut [T]) {
189 if block0 < block1 {
190 let (s0, s1) = self.data.split_at_mut(block1);
191 (&mut s0[block0..], s1)
192 } else {
193 let (s1, s0) = self.data.split_at_mut(block0);
194 (s0, &mut s1[block1..])
195 }
196 }
197
198 fn realloc(
202 &mut self,
203 block: usize,
204 from_sclass: SizeClass,
205 to_sclass: SizeClass,
206 elems_to_copy: usize,
207 ) -> usize {
208 debug_assert!(elems_to_copy <= sclass_size(from_sclass));
209 debug_assert!(elems_to_copy <= sclass_size(to_sclass));
210 let new_block = self.alloc(to_sclass);
211
212 if elems_to_copy > 0 {
213 let (old, new) = self.mut_slices(block, new_block);
214 (&mut new[0..elems_to_copy]).copy_from_slice(&old[0..elems_to_copy]);
215 }
216
217 self.free(block, from_sclass);
218 new_block
219 }
220}
221
222impl<T: EntityRef> EntityList<T> {
223 pub fn new() -> Self {
225 Default::default()
226 }
227
228 pub fn from_slice(slice: &[T], pool: &mut ListPool<T>) -> Self {
230 let len = slice.len();
231 if len == 0 {
232 return EntityList::new();
233 }
234
235 let block = pool.alloc(sclass_for_length(len));
236 pool.data[block] = T::new(len);
237 pool.data[block + 1..block + len + 1].copy_from_slice(slice);
238
239 EntityList {
240 index: (block + 1) as u32,
241 unused: PhantomData,
242 }
243 }
244
245 pub fn is_empty(&self) -> bool {
247 self.index == 0
250 }
251
252 pub fn len(&self, pool: &ListPool<T>) -> usize {
254 pool.len_of(self).unwrap_or(0)
256 }
257
258 pub fn is_valid(&self, pool: &ListPool<T>) -> bool {
260 self.is_empty() || pool.len_of(self) != None
262 }
263
264 pub fn as_slice<'a>(&'a self, pool: &'a ListPool<T>) -> &'a [T] {
266 let idx = self.index as usize;
267 match pool.len_of(self) {
268 None => &[],
269 Some(len) => &pool.data[idx..idx + len],
270 }
271 }
272
273 pub fn get(&self, index: usize, pool: &ListPool<T>) -> Option<T> {
275 self.as_slice(pool).get(index).cloned()
276 }
277
278 pub fn first(&self, pool: &ListPool<T>) -> Option<T> {
280 if self.is_empty() {
281 None
282 } else {
283 Some(pool.data[self.index as usize])
284 }
285 }
286
287 pub fn as_mut_slice<'a>(&'a mut self, pool: &'a mut ListPool<T>) -> &'a mut [T] {
289 let idx = self.index as usize;
290 match pool.len_of(self) {
291 None => &mut [],
292 Some(len) => &mut pool.data[idx..idx + len],
293 }
294 }
295
296 pub fn get_mut<'a>(&'a mut self, index: usize, pool: &'a mut ListPool<T>) -> Option<&'a mut T> {
298 self.as_mut_slice(pool).get_mut(index)
299 }
300
301 pub fn clear(&mut self, pool: &mut ListPool<T>) {
305 let idx = self.index as usize;
306 match pool.len_of(self) {
307 None => debug_assert_eq!(idx, 0, "Invalid pool"),
308 Some(len) => pool.free(idx - 1, sclass_for_length(len)),
309 }
310 self.index = 0;
312 }
313
314 pub fn take(&mut self) -> Self {
318 mem::replace(self, Default::default())
319 }
320
321 pub fn push(&mut self, element: T, pool: &mut ListPool<T>) -> usize {
324 let idx = self.index as usize;
325 match pool.len_of(self) {
326 None => {
327 debug_assert_eq!(idx, 0, "Invalid pool");
329 let block = pool.alloc(sclass_for_length(1));
330 pool.data[block] = T::new(1);
331 pool.data[block + 1] = element;
332 self.index = (block + 1) as u32;
333 0
334 }
335 Some(len) => {
336 let new_len = len + 1;
338 let block;
339 if is_sclass_min_length(new_len) {
340 let sclass = sclass_for_length(len);
342 block = pool.realloc(idx - 1, sclass, sclass + 1, len + 1);
343 self.index = (block + 1) as u32;
344 } else {
345 block = idx - 1;
346 }
347 pool.data[block + new_len] = element;
348 pool.data[block] = T::new(new_len);
349 len
350 }
351 }
352 }
353
354 fn grow<'a>(&'a mut self, count: usize, pool: &'a mut ListPool<T>) -> &'a mut [T] {
358 let idx = self.index as usize;
359 let new_len;
360 let block;
361 match pool.len_of(self) {
362 None => {
363 debug_assert_eq!(idx, 0, "Invalid pool");
365 if count == 0 {
366 return &mut [];
367 }
368 new_len = count;
369 block = pool.alloc(sclass_for_length(new_len));
370 self.index = (block + 1) as u32;
371 }
372 Some(len) => {
373 let sclass = sclass_for_length(len);
375 new_len = len + count;
376 let new_sclass = sclass_for_length(new_len);
377 if new_sclass != sclass {
378 block = pool.realloc(idx - 1, sclass, new_sclass, len + 1);
379 self.index = (block + 1) as u32;
380 } else {
381 block = idx - 1;
382 }
383 }
384 }
385 pool.data[block] = T::new(new_len);
386 &mut pool.data[block + 1..block + 1 + new_len]
387 }
388
389 pub fn extend<I>(&mut self, elements: I, pool: &mut ListPool<T>)
391 where
392 I: IntoIterator<Item = T>,
393 {
394 for x in elements {
396 self.push(x, pool);
397 }
398 }
399
400 pub fn insert(&mut self, index: usize, element: T, pool: &mut ListPool<T>) {
403 self.push(element, pool);
405
406 let seq = self.as_mut_slice(pool);
408 if index < seq.len() {
409 let tail = &mut seq[index..];
410 for i in (1..tail.len()).rev() {
411 tail[i] = tail[i - 1];
412 }
413 tail[0] = element;
414 } else {
415 debug_assert_eq!(index, seq.len());
416 }
417 }
418
419 pub fn remove(&mut self, index: usize, pool: &mut ListPool<T>) {
421 let len;
422 {
423 let seq = self.as_mut_slice(pool);
424 len = seq.len();
425 debug_assert!(index < len);
426
427 for i in index..len - 1 {
429 seq[i] = seq[i + 1];
430 }
431 }
432
433 if len == 1 {
435 self.clear(pool);
436 return;
437 }
438
439 let mut block = self.index as usize - 1;
441 if is_sclass_min_length(len) {
442 let sclass = sclass_for_length(len);
443 block = pool.realloc(block, sclass, sclass - 1, len);
444 self.index = (block + 1) as u32;
445 }
446
447 pool.data[block] = T::new(len - 1);
449 }
450
451 pub fn swap_remove(&mut self, index: usize, pool: &mut ListPool<T>) {
454 let len = self.len(pool);
455 debug_assert!(index < len);
456 if index == len - 1 {
457 self.remove(index, pool);
458 } else {
459 {
460 let seq = self.as_mut_slice(pool);
461 seq.swap(index, len - 1);
462 }
463 self.remove(len - 1, pool);
464 }
465 }
466
467 pub fn grow_at(&mut self, index: usize, count: usize, pool: &mut ListPool<T>) {
473 let data = self.grow(count, pool);
474
475 for i in (index + count..data.len()).rev() {
477 data[i] = data[i - count];
478 }
479 }
480}
481
482#[cfg(test)]
483mod tests {
484 use super::*;
485 use super::{sclass_for_length, sclass_size};
486 use EntityRef;
487
488 #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
490 pub struct Inst(u32);
491 entity_impl!(Inst, "inst");
492
493 #[test]
494 fn size_classes() {
495 assert_eq!(sclass_size(0), 4);
496 assert_eq!(sclass_for_length(0), 0);
497 assert_eq!(sclass_for_length(1), 0);
498 assert_eq!(sclass_for_length(2), 0);
499 assert_eq!(sclass_for_length(3), 0);
500 assert_eq!(sclass_for_length(4), 1);
501 assert_eq!(sclass_for_length(7), 1);
502 assert_eq!(sclass_for_length(8), 2);
503 assert_eq!(sclass_size(1), 8);
504 for l in 0..300 {
505 assert!(sclass_size(sclass_for_length(l)) >= l + 1);
506 }
507 }
508
509 #[test]
510 fn block_allocator() {
511 let mut pool = ListPool::<Inst>::new();
512 let b1 = pool.alloc(0);
513 let b2 = pool.alloc(1);
514 let b3 = pool.alloc(0);
515 assert_ne!(b1, b2);
516 assert_ne!(b1, b3);
517 assert_ne!(b2, b3);
518 pool.free(b2, 1);
519 let b2a = pool.alloc(1);
520 let b2b = pool.alloc(1);
521 assert_ne!(b2a, b2b);
522 assert!(b2a == b2 || b2b == b2);
524
525 pool.free(b1, 0);
527 pool.free(b3, 0);
528 let b1a = pool.alloc(0);
529 let b3a = pool.alloc(0);
530 assert_ne!(b1a, b3a);
531 assert!(b1a == b1 || b1a == b3);
532 assert!(b3a == b1 || b3a == b3);
533 }
534
535 #[test]
536 fn empty_list() {
537 let pool = &mut ListPool::<Inst>::new();
538 let mut list = EntityList::<Inst>::default();
539 {
540 let ilist = &list;
541 assert!(ilist.is_empty());
542 assert_eq!(ilist.len(pool), 0);
543 assert_eq!(ilist.as_slice(pool), &[]);
544 assert_eq!(ilist.get(0, pool), None);
545 assert_eq!(ilist.get(100, pool), None);
546 }
547 assert_eq!(list.as_mut_slice(pool), &[]);
548 assert_eq!(list.get_mut(0, pool), None);
549 assert_eq!(list.get_mut(100, pool), None);
550
551 list.clear(pool);
552 assert!(list.is_empty());
553 assert_eq!(list.len(pool), 0);
554 assert_eq!(list.as_slice(pool), &[]);
555 assert_eq!(list.first(pool), None);
556 }
557
558 #[test]
559 fn from_slice() {
560 let pool = &mut ListPool::<Inst>::new();
561
562 let list = EntityList::<Inst>::from_slice(&[Inst(0), Inst(1)], pool);
563 assert!(!list.is_empty());
564 assert_eq!(list.len(pool), 2);
565 assert_eq!(list.as_slice(pool), &[Inst(0), Inst(1)]);
566 assert_eq!(list.get(0, pool), Some(Inst(0)));
567 assert_eq!(list.get(100, pool), None);
568
569 let list = EntityList::<Inst>::from_slice(&[], pool);
570 assert!(list.is_empty());
571 assert_eq!(list.len(pool), 0);
572 assert_eq!(list.as_slice(pool), &[]);
573 assert_eq!(list.get(0, pool), None);
574 assert_eq!(list.get(100, pool), None);
575 }
576
577 #[test]
578 fn push() {
579 let pool = &mut ListPool::<Inst>::new();
580 let mut list = EntityList::<Inst>::default();
581
582 let i1 = Inst::new(1);
583 let i2 = Inst::new(2);
584 let i3 = Inst::new(3);
585 let i4 = Inst::new(4);
586
587 assert_eq!(list.push(i1, pool), 0);
588 assert_eq!(list.len(pool), 1);
589 assert!(!list.is_empty());
590 assert_eq!(list.as_slice(pool), &[i1]);
591 assert_eq!(list.first(pool), Some(i1));
592 assert_eq!(list.get(0, pool), Some(i1));
593 assert_eq!(list.get(1, pool), None);
594
595 assert_eq!(list.push(i2, pool), 1);
596 assert_eq!(list.len(pool), 2);
597 assert!(!list.is_empty());
598 assert_eq!(list.as_slice(pool), &[i1, i2]);
599 assert_eq!(list.first(pool), Some(i1));
600 assert_eq!(list.get(0, pool), Some(i1));
601 assert_eq!(list.get(1, pool), Some(i2));
602 assert_eq!(list.get(2, pool), None);
603
604 assert_eq!(list.push(i3, pool), 2);
605 assert_eq!(list.len(pool), 3);
606 assert!(!list.is_empty());
607 assert_eq!(list.as_slice(pool), &[i1, i2, i3]);
608 assert_eq!(list.first(pool), Some(i1));
609 assert_eq!(list.get(0, pool), Some(i1));
610 assert_eq!(list.get(1, pool), Some(i2));
611 assert_eq!(list.get(2, pool), Some(i3));
612 assert_eq!(list.get(3, pool), None);
613
614 assert_eq!(list.push(i4, pool), 3);
616 assert_eq!(list.len(pool), 4);
617 assert!(!list.is_empty());
618 assert_eq!(list.as_slice(pool), &[i1, i2, i3, i4]);
619 assert_eq!(list.first(pool), Some(i1));
620 assert_eq!(list.get(0, pool), Some(i1));
621 assert_eq!(list.get(1, pool), Some(i2));
622 assert_eq!(list.get(2, pool), Some(i3));
623 assert_eq!(list.get(3, pool), Some(i4));
624 assert_eq!(list.get(4, pool), None);
625
626 list.extend([i1, i1, i2, i2, i3, i3, i4, i4].iter().cloned(), pool);
627 assert_eq!(list.len(pool), 12);
628 assert_eq!(
629 list.as_slice(pool),
630 &[i1, i2, i3, i4, i1, i1, i2, i2, i3, i3, i4, i4]
631 );
632 }
633
634 #[test]
635 fn insert_remove() {
636 let pool = &mut ListPool::<Inst>::new();
637 let mut list = EntityList::<Inst>::default();
638
639 let i1 = Inst::new(1);
640 let i2 = Inst::new(2);
641 let i3 = Inst::new(3);
642 let i4 = Inst::new(4);
643
644 list.insert(0, i4, pool);
645 assert_eq!(list.as_slice(pool), &[i4]);
646
647 list.insert(0, i3, pool);
648 assert_eq!(list.as_slice(pool), &[i3, i4]);
649
650 list.insert(2, i2, pool);
651 assert_eq!(list.as_slice(pool), &[i3, i4, i2]);
652
653 list.insert(2, i1, pool);
654 assert_eq!(list.as_slice(pool), &[i3, i4, i1, i2]);
655
656 list.remove(3, pool);
657 assert_eq!(list.as_slice(pool), &[i3, i4, i1]);
658
659 list.remove(2, pool);
660 assert_eq!(list.as_slice(pool), &[i3, i4]);
661
662 list.remove(0, pool);
663 assert_eq!(list.as_slice(pool), &[i4]);
664
665 list.remove(0, pool);
666 assert_eq!(list.as_slice(pool), &[]);
667 assert!(list.is_empty());
668 }
669
670 #[test]
671 fn growing() {
672 let pool = &mut ListPool::<Inst>::new();
673 let mut list = EntityList::<Inst>::default();
674
675 let i1 = Inst::new(1);
676 let i2 = Inst::new(2);
677 let i3 = Inst::new(3);
678 let i4 = Inst::new(4);
679
680 list.grow_at(0, 0, pool);
682 assert_eq!(list.len(pool), 0);
683 assert!(list.is_empty());
684
685 list.grow_at(0, 2, pool);
686 assert_eq!(list.len(pool), 2);
687
688 list.as_mut_slice(pool).copy_from_slice(&[i2, i3]);
689
690 list.grow_at(1, 0, pool);
691 assert_eq!(list.as_slice(pool), &[i2, i3]);
692
693 list.grow_at(1, 1, pool);
694 list.as_mut_slice(pool)[1] = i1;
695 assert_eq!(list.as_slice(pool), &[i2, i1, i3]);
696
697 list.grow_at(3, 0, pool);
699 assert_eq!(list.as_slice(pool), &[i2, i1, i3]);
700
701 list.grow_at(3, 1, pool);
703 list.as_mut_slice(pool)[3] = i4;
704 assert_eq!(list.as_slice(pool), &[i2, i1, i3, i4]);
705 }
706}