1use crate::packed_option::ReservedValue;
3use crate::EntityRef;
4use alloc::vec::Vec;
5use core::marker::PhantomData;
6use core::mem;
7
8#[cfg(feature = "enable-serde")]
9use serde::{Deserialize, Serialize};
10
11#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
66#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
67pub struct EntityList<T: EntityRef + ReservedValue> {
68 index: u32,
69 unused: PhantomData<T>,
70}
71
72impl<T: EntityRef + ReservedValue> Default for EntityList<T> {
74 fn default() -> Self {
75 Self {
76 index: 0,
77 unused: PhantomData,
78 }
79 }
80}
81
82#[derive(Clone, Debug)]
84#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
85pub struct ListPool<T: EntityRef + ReservedValue> {
86 data: Vec<T>,
88
89 free: Vec<usize>,
91}
92
93impl<T: EntityRef + ReservedValue> PartialEq for ListPool<T> {
94 fn eq(&self, other: &Self) -> bool {
95 self.data == other.data
97 }
98}
99
100impl<T: core::hash::Hash + EntityRef + ReservedValue> core::hash::Hash for ListPool<T> {
101 fn hash<H: __core::hash::Hasher>(&self, state: &mut H) {
102 self.data.hash(state);
104 }
105}
106
107impl<T: EntityRef + ReservedValue> Default for ListPool<T> {
108 fn default() -> Self {
109 Self::new()
110 }
111}
112
113type SizeClass = u8;
116
117#[inline]
120fn sclass_size(sclass: SizeClass) -> usize {
121 4 << sclass
122}
123
124#[inline]
127fn sclass_for_length(len: usize) -> SizeClass {
128 30 - (len as u32 | 3).leading_zeros() as SizeClass
129}
130
131#[inline]
133fn is_sclass_min_length(len: usize) -> bool {
134 len > 3 && len.is_power_of_two()
135}
136
137impl<T: EntityRef + ReservedValue> ListPool<T> {
138 pub fn new() -> Self {
140 Self {
141 data: Vec::new(),
142 free: Vec::new(),
143 }
144 }
145
146 pub fn with_capacity(len: usize) -> Self {
148 Self {
149 data: Vec::with_capacity(len),
150 free: Vec::new(),
151 }
152 }
153
154 pub fn capacity(&self) -> usize {
161 self.data.capacity()
162 }
163
164 pub fn clear(&mut self) {
171 self.data.clear();
172 self.free.clear();
173 }
174
175 fn len_of(&self, list: &EntityList<T>) -> Option<usize> {
177 let idx = list.index as usize;
178 self.data.get(idx.wrapping_sub(1)).map(|len| len.index())
185 }
186
187 fn alloc(&mut self, sclass: SizeClass) -> usize {
193 match self.free.get(sclass as usize).cloned() {
195 Some(head) if head > 0 => {
196 self.free[sclass as usize] = self.data[head].index();
201 head - 1
202 }
203 _ => {
204 let offset = self.data.len();
206 self.data
207 .resize(offset + sclass_size(sclass), T::reserved_value());
208 offset
209 }
210 }
211 }
212
213 fn free(&mut self, block: usize, sclass: SizeClass) {
217 let sclass = sclass as usize;
218
219 if self.free.len() <= sclass {
221 self.free.resize(sclass + 1, 0);
222 }
223
224 self.data[block] = T::new(0);
226 self.data[block + 1] = T::new(self.free[sclass]);
228 self.free[sclass] = block + 1
229 }
230
231 fn mut_slices(&mut self, block0: usize, block1: usize) -> (&mut [T], &mut [T]) {
236 if block0 < block1 {
237 let (s0, s1) = self.data.split_at_mut(block1);
238 (&mut s0[block0..], s1)
239 } else {
240 let (s1, s0) = self.data.split_at_mut(block0);
241 (s0, &mut s1[block1..])
242 }
243 }
244
245 fn realloc(
249 &mut self,
250 block: usize,
251 from_sclass: SizeClass,
252 to_sclass: SizeClass,
253 elems_to_copy: usize,
254 ) -> usize {
255 debug_assert!(elems_to_copy <= sclass_size(from_sclass));
256 debug_assert!(elems_to_copy <= sclass_size(to_sclass));
257 let new_block = self.alloc(to_sclass);
258
259 if elems_to_copy > 0 {
260 let (old, new) = self.mut_slices(block, new_block);
261 (&mut new[0..elems_to_copy]).copy_from_slice(&old[0..elems_to_copy]);
262 }
263
264 self.free(block, from_sclass);
265 new_block
266 }
267}
268
269impl<T: EntityRef + ReservedValue> EntityList<T> {
270 pub fn new() -> Self {
272 Default::default()
273 }
274
275 pub fn from_slice(slice: &[T], pool: &mut ListPool<T>) -> Self {
277 let len = slice.len();
278 if len == 0 {
279 return Self::new();
280 }
281
282 let block = pool.alloc(sclass_for_length(len));
283 pool.data[block] = T::new(len);
284 pool.data[block + 1..=block + len].copy_from_slice(slice);
285
286 Self {
287 index: (block + 1) as u32,
288 unused: PhantomData,
289 }
290 }
291
292 pub fn is_empty(&self) -> bool {
294 self.index == 0
297 }
298
299 pub fn len(&self, pool: &ListPool<T>) -> usize {
301 pool.len_of(self).unwrap_or(0)
303 }
304
305 pub fn is_valid(&self, pool: &ListPool<T>) -> bool {
307 self.is_empty() || pool.len_of(self) != None
309 }
310
311 pub fn as_slice<'a>(&self, pool: &'a ListPool<T>) -> &'a [T] {
313 let idx = self.index as usize;
314 match pool.len_of(self) {
315 None => &[],
316 Some(len) => &pool.data[idx..idx + len],
317 }
318 }
319
320 pub fn get(&self, index: usize, pool: &ListPool<T>) -> Option<T> {
322 self.as_slice(pool).get(index).cloned()
323 }
324
325 pub fn first(&self, pool: &ListPool<T>) -> Option<T> {
327 if self.is_empty() {
328 None
329 } else {
330 Some(pool.data[self.index as usize])
331 }
332 }
333
334 pub fn as_mut_slice<'a>(&'a mut self, pool: &'a mut ListPool<T>) -> &'a mut [T] {
336 let idx = self.index as usize;
337 match pool.len_of(self) {
338 None => &mut [],
339 Some(len) => &mut pool.data[idx..idx + len],
340 }
341 }
342
343 pub fn get_mut<'a>(&'a mut self, index: usize, pool: &'a mut ListPool<T>) -> Option<&'a mut T> {
345 self.as_mut_slice(pool).get_mut(index)
346 }
347
348 pub fn deep_clone(&self, pool: &mut ListPool<T>) -> Self {
350 match pool.len_of(self) {
351 None => return Self::new(),
352 Some(len) => {
353 let src = self.index as usize;
354 let block = pool.alloc(sclass_for_length(len));
355 pool.data[block] = T::new(len);
356 pool.data.copy_within(src..src + len, block + 1);
357
358 Self {
359 index: (block + 1) as u32,
360 unused: PhantomData,
361 }
362 }
363 }
364 }
365
366 pub fn clear(&mut self, pool: &mut ListPool<T>) {
370 let idx = self.index as usize;
371 match pool.len_of(self) {
372 None => debug_assert_eq!(idx, 0, "Invalid pool"),
373 Some(len) => pool.free(idx - 1, sclass_for_length(len)),
374 }
375 self.index = 0;
377 }
378
379 pub fn take(&mut self) -> Self {
383 mem::replace(self, Default::default())
384 }
385
386 pub fn push(&mut self, element: T, pool: &mut ListPool<T>) -> usize {
389 let idx = self.index as usize;
390 match pool.len_of(self) {
391 None => {
392 debug_assert_eq!(idx, 0, "Invalid pool");
394 let block = pool.alloc(sclass_for_length(1));
395 pool.data[block] = T::new(1);
396 pool.data[block + 1] = element;
397 self.index = (block + 1) as u32;
398 0
399 }
400 Some(len) => {
401 let new_len = len + 1;
403 let block;
404 if is_sclass_min_length(new_len) {
405 let sclass = sclass_for_length(len);
407 block = pool.realloc(idx - 1, sclass, sclass + 1, len + 1);
408 self.index = (block + 1) as u32;
409 } else {
410 block = idx - 1;
411 }
412 pool.data[block + new_len] = element;
413 pool.data[block] = T::new(new_len);
414 len
415 }
416 }
417 }
418
419 fn grow<'a>(&'a mut self, count: usize, pool: &'a mut ListPool<T>) -> &'a mut [T] {
423 let idx = self.index as usize;
424 let new_len;
425 let block;
426 match pool.len_of(self) {
427 None => {
428 debug_assert_eq!(idx, 0, "Invalid pool");
430 if count == 0 {
431 return &mut [];
432 }
433 new_len = count;
434 block = pool.alloc(sclass_for_length(new_len));
435 self.index = (block + 1) as u32;
436 }
437 Some(len) => {
438 let sclass = sclass_for_length(len);
440 new_len = len + count;
441 let new_sclass = sclass_for_length(new_len);
442 if new_sclass != sclass {
443 block = pool.realloc(idx - 1, sclass, new_sclass, len + 1);
444 self.index = (block + 1) as u32;
445 } else {
446 block = idx - 1;
447 }
448 }
449 }
450 pool.data[block] = T::new(new_len);
451 &mut pool.data[block + 1..block + 1 + new_len]
452 }
453
454 pub fn from_iter<I>(elements: I, pool: &mut ListPool<T>) -> Self
456 where
457 I: IntoIterator<Item = T>,
458 {
459 let mut list = Self::new();
460 list.extend(elements, pool);
461 list
462 }
463
464 pub fn extend<I>(&mut self, elements: I, pool: &mut ListPool<T>)
466 where
467 I: IntoIterator<Item = T>,
468 {
469 let iterator = elements.into_iter();
470 let (len, upper) = iterator.size_hint();
471 if upper == Some(len) {
473 let data = self.grow(len, pool);
474 let offset = data.len() - len;
475 for (src, dst) in iterator.zip(data[offset..].iter_mut()) {
476 *dst = src;
477 }
478 } else {
479 for x in iterator {
480 self.push(x, pool);
481 }
482 }
483 }
484
485 pub fn insert(&mut self, index: usize, element: T, pool: &mut ListPool<T>) {
488 self.push(element, pool);
490
491 let seq = self.as_mut_slice(pool);
493 if index < seq.len() {
494 let tail = &mut seq[index..];
495 for i in (1..tail.len()).rev() {
496 tail[i] = tail[i - 1];
497 }
498 tail[0] = element;
499 } else {
500 debug_assert_eq!(index, seq.len());
501 }
502 }
503
504 fn remove_last(&mut self, len: usize, pool: &mut ListPool<T>) {
506 if len == 1 {
508 self.clear(pool);
509 return;
510 }
511
512 let mut block = self.index as usize - 1;
514 if is_sclass_min_length(len) {
515 let sclass = sclass_for_length(len);
516 block = pool.realloc(block, sclass, sclass - 1, len);
517 self.index = (block + 1) as u32;
518 }
519
520 pool.data[block] = T::new(len - 1);
522 }
523
524 pub fn remove(&mut self, index: usize, pool: &mut ListPool<T>) {
526 let len;
527 {
528 let seq = self.as_mut_slice(pool);
529 len = seq.len();
530 debug_assert!(index < len);
531
532 for i in index..len - 1 {
534 seq[i] = seq[i + 1];
535 }
536 }
537
538 self.remove_last(len, pool);
539 }
540
541 pub fn swap_remove(&mut self, index: usize, pool: &mut ListPool<T>) {
544 let seq = self.as_mut_slice(pool);
545 let len = seq.len();
546 debug_assert!(index < len);
547 if index != len - 1 {
548 seq.swap(index, len - 1);
549 }
550
551 self.remove_last(len, pool);
552 }
553
554 pub fn truncate(&mut self, new_len: usize, pool: &mut ListPool<T>) {
558 if new_len == 0 {
559 self.clear(pool);
560 return;
561 }
562
563 match pool.len_of(self) {
564 None => return,
565 Some(len) => {
566 if len <= new_len {
567 return;
568 }
569
570 let block;
571 let idx = self.index as usize;
572 let sclass = sclass_for_length(len);
573 let new_sclass = sclass_for_length(new_len);
574 if sclass != new_sclass {
575 block = pool.realloc(idx - 1, sclass, new_sclass, new_len + 1);
576 self.index = (block + 1) as u32;
577 } else {
578 block = idx - 1;
579 }
580 pool.data[block] = T::new(new_len);
581 }
582 }
583 }
584
585 pub fn grow_at(&mut self, index: usize, count: usize, pool: &mut ListPool<T>) {
591 let data = self.grow(count, pool);
592
593 for i in (index + count..data.len()).rev() {
595 data[i] = data[i - count];
596 }
597 }
598}
599
600#[cfg(test)]
601mod tests {
602 use super::*;
603 use super::{sclass_for_length, sclass_size};
604 use crate::EntityRef;
605
606 #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
608 pub struct Inst(u32);
609 entity_impl!(Inst, "inst");
610
611 #[test]
612 fn size_classes() {
613 assert_eq!(sclass_size(0), 4);
614 assert_eq!(sclass_for_length(0), 0);
615 assert_eq!(sclass_for_length(1), 0);
616 assert_eq!(sclass_for_length(2), 0);
617 assert_eq!(sclass_for_length(3), 0);
618 assert_eq!(sclass_for_length(4), 1);
619 assert_eq!(sclass_for_length(7), 1);
620 assert_eq!(sclass_for_length(8), 2);
621 assert_eq!(sclass_size(1), 8);
622 for l in 0..300 {
623 assert!(sclass_size(sclass_for_length(l)) >= l + 1);
624 }
625 }
626
627 #[test]
628 fn block_allocator() {
629 let mut pool = ListPool::<Inst>::new();
630 let b1 = pool.alloc(0);
631 let b2 = pool.alloc(1);
632 let b3 = pool.alloc(0);
633 assert_ne!(b1, b2);
634 assert_ne!(b1, b3);
635 assert_ne!(b2, b3);
636 pool.free(b2, 1);
637 let b2a = pool.alloc(1);
638 let b2b = pool.alloc(1);
639 assert_ne!(b2a, b2b);
640 assert!(b2a == b2 || b2b == b2);
642
643 pool.free(b1, 0);
645 pool.free(b3, 0);
646 let b1a = pool.alloc(0);
647 let b3a = pool.alloc(0);
648 assert_ne!(b1a, b3a);
649 assert!(b1a == b1 || b1a == b3);
650 assert!(b3a == b1 || b3a == b3);
651 }
652
653 #[test]
654 fn empty_list() {
655 let pool = &mut ListPool::<Inst>::new();
656 let mut list = EntityList::<Inst>::default();
657 {
658 let ilist = &list;
659 assert!(ilist.is_empty());
660 assert_eq!(ilist.len(pool), 0);
661 assert_eq!(ilist.as_slice(pool), &[]);
662 assert_eq!(ilist.get(0, pool), None);
663 assert_eq!(ilist.get(100, pool), None);
664 }
665 assert_eq!(list.as_mut_slice(pool), &[]);
666 assert_eq!(list.get_mut(0, pool), None);
667 assert_eq!(list.get_mut(100, pool), None);
668
669 list.clear(pool);
670 assert!(list.is_empty());
671 assert_eq!(list.len(pool), 0);
672 assert_eq!(list.as_slice(pool), &[]);
673 assert_eq!(list.first(pool), None);
674 }
675
676 #[test]
677 fn from_slice() {
678 let pool = &mut ListPool::<Inst>::new();
679
680 let list = EntityList::<Inst>::from_slice(&[Inst(0), Inst(1)], pool);
681 assert!(!list.is_empty());
682 assert_eq!(list.len(pool), 2);
683 assert_eq!(list.as_slice(pool), &[Inst(0), Inst(1)]);
684 assert_eq!(list.get(0, pool), Some(Inst(0)));
685 assert_eq!(list.get(100, pool), None);
686
687 let list = EntityList::<Inst>::from_slice(&[], pool);
688 assert!(list.is_empty());
689 assert_eq!(list.len(pool), 0);
690 assert_eq!(list.as_slice(pool), &[]);
691 assert_eq!(list.get(0, pool), None);
692 assert_eq!(list.get(100, pool), None);
693 }
694
695 #[test]
696 fn push() {
697 let pool = &mut ListPool::<Inst>::new();
698 let mut list = EntityList::<Inst>::default();
699
700 let i1 = Inst::new(1);
701 let i2 = Inst::new(2);
702 let i3 = Inst::new(3);
703 let i4 = Inst::new(4);
704
705 assert_eq!(list.push(i1, pool), 0);
706 assert_eq!(list.len(pool), 1);
707 assert!(!list.is_empty());
708 assert_eq!(list.as_slice(pool), &[i1]);
709 assert_eq!(list.first(pool), Some(i1));
710 assert_eq!(list.get(0, pool), Some(i1));
711 assert_eq!(list.get(1, pool), None);
712
713 assert_eq!(list.push(i2, pool), 1);
714 assert_eq!(list.len(pool), 2);
715 assert!(!list.is_empty());
716 assert_eq!(list.as_slice(pool), &[i1, i2]);
717 assert_eq!(list.first(pool), Some(i1));
718 assert_eq!(list.get(0, pool), Some(i1));
719 assert_eq!(list.get(1, pool), Some(i2));
720 assert_eq!(list.get(2, pool), None);
721
722 assert_eq!(list.push(i3, pool), 2);
723 assert_eq!(list.len(pool), 3);
724 assert!(!list.is_empty());
725 assert_eq!(list.as_slice(pool), &[i1, i2, i3]);
726 assert_eq!(list.first(pool), Some(i1));
727 assert_eq!(list.get(0, pool), Some(i1));
728 assert_eq!(list.get(1, pool), Some(i2));
729 assert_eq!(list.get(2, pool), Some(i3));
730 assert_eq!(list.get(3, pool), None);
731
732 assert_eq!(list.push(i4, pool), 3);
734 assert_eq!(list.len(pool), 4);
735 assert!(!list.is_empty());
736 assert_eq!(list.as_slice(pool), &[i1, i2, i3, i4]);
737 assert_eq!(list.first(pool), Some(i1));
738 assert_eq!(list.get(0, pool), Some(i1));
739 assert_eq!(list.get(1, pool), Some(i2));
740 assert_eq!(list.get(2, pool), Some(i3));
741 assert_eq!(list.get(3, pool), Some(i4));
742 assert_eq!(list.get(4, pool), None);
743
744 list.extend([i1, i1, i2, i2, i3, i3, i4, i4].iter().cloned(), pool);
745 assert_eq!(list.len(pool), 12);
746 assert_eq!(
747 list.as_slice(pool),
748 &[i1, i2, i3, i4, i1, i1, i2, i2, i3, i3, i4, i4]
749 );
750
751 let list2 = EntityList::from_iter([i1, i1, i2, i2, i3, i3, i4, i4].iter().cloned(), pool);
752 assert_eq!(list2.len(pool), 8);
753 assert_eq!(list2.as_slice(pool), &[i1, i1, i2, i2, i3, i3, i4, i4]);
754 }
755
756 #[test]
757 fn insert_remove() {
758 let pool = &mut ListPool::<Inst>::new();
759 let mut list = EntityList::<Inst>::default();
760
761 let i1 = Inst::new(1);
762 let i2 = Inst::new(2);
763 let i3 = Inst::new(3);
764 let i4 = Inst::new(4);
765
766 list.insert(0, i4, pool);
767 assert_eq!(list.as_slice(pool), &[i4]);
768
769 list.insert(0, i3, pool);
770 assert_eq!(list.as_slice(pool), &[i3, i4]);
771
772 list.insert(2, i2, pool);
773 assert_eq!(list.as_slice(pool), &[i3, i4, i2]);
774
775 list.insert(2, i1, pool);
776 assert_eq!(list.as_slice(pool), &[i3, i4, i1, i2]);
777
778 list.remove(3, pool);
779 assert_eq!(list.as_slice(pool), &[i3, i4, i1]);
780
781 list.remove(2, pool);
782 assert_eq!(list.as_slice(pool), &[i3, i4]);
783
784 list.remove(0, pool);
785 assert_eq!(list.as_slice(pool), &[i4]);
786
787 list.remove(0, pool);
788 assert_eq!(list.as_slice(pool), &[]);
789 assert!(list.is_empty());
790 }
791
792 #[test]
793 fn growing() {
794 let pool = &mut ListPool::<Inst>::new();
795 let mut list = EntityList::<Inst>::default();
796
797 let i1 = Inst::new(1);
798 let i2 = Inst::new(2);
799 let i3 = Inst::new(3);
800 let i4 = Inst::new(4);
801
802 list.grow_at(0, 0, pool);
804 assert_eq!(list.len(pool), 0);
805 assert!(list.is_empty());
806
807 list.grow_at(0, 2, pool);
808 assert_eq!(list.len(pool), 2);
809
810 list.as_mut_slice(pool).copy_from_slice(&[i2, i3]);
811
812 list.grow_at(1, 0, pool);
813 assert_eq!(list.as_slice(pool), &[i2, i3]);
814
815 list.grow_at(1, 1, pool);
816 list.as_mut_slice(pool)[1] = i1;
817 assert_eq!(list.as_slice(pool), &[i2, i1, i3]);
818
819 list.grow_at(3, 0, pool);
821 assert_eq!(list.as_slice(pool), &[i2, i1, i3]);
822
823 list.grow_at(3, 1, pool);
825 list.as_mut_slice(pool)[3] = i4;
826 assert_eq!(list.as_slice(pool), &[i2, i1, i3, i4]);
827 }
828
829 #[test]
830 fn deep_clone() {
831 let pool = &mut ListPool::<Inst>::new();
832
833 let i1 = Inst::new(1);
834 let i2 = Inst::new(2);
835 let i3 = Inst::new(3);
836 let i4 = Inst::new(4);
837
838 let mut list1 = EntityList::from_slice(&[i1, i2, i3], pool);
839 let list2 = list1.deep_clone(pool);
840 assert_eq!(list1.as_slice(pool), &[i1, i2, i3]);
841 assert_eq!(list2.as_slice(pool), &[i1, i2, i3]);
842
843 list1.as_mut_slice(pool)[0] = i4;
844 assert_eq!(list1.as_slice(pool), &[i4, i2, i3]);
845 assert_eq!(list2.as_slice(pool), &[i1, i2, i3]);
846 }
847
848 #[test]
849 fn truncate() {
850 let pool = &mut ListPool::<Inst>::new();
851
852 let i1 = Inst::new(1);
853 let i2 = Inst::new(2);
854 let i3 = Inst::new(3);
855 let i4 = Inst::new(4);
856
857 let mut list = EntityList::from_slice(&[i1, i2, i3, i4, i1, i2, i3, i4], pool);
858 assert_eq!(list.as_slice(pool), &[i1, i2, i3, i4, i1, i2, i3, i4]);
859 list.truncate(6, pool);
860 assert_eq!(list.as_slice(pool), &[i1, i2, i3, i4, i1, i2]);
861 list.truncate(9, pool);
862 assert_eq!(list.as_slice(pool), &[i1, i2, i3, i4, i1, i2]);
863 list.truncate(2, pool);
864 assert_eq!(list.as_slice(pool), &[i1, i2]);
865 list.truncate(0, pool);
866 assert!(list.is_empty());
867 }
868}