1use core::convert::TryInto;
2use core::mem::replace;
3use core::ops;
4
5#[cfg(not(feature = "std"))]
7use alloc::vec::Vec;
8
9use crate::free_pointer::FreePointer;
10use crate::generation::Generation;
11use crate::iter::{Drain, IntoIter, Iter, IterMut};
12
13#[derive(Debug, Clone)]
17pub struct Arena<T> {
18 storage: Vec<Entry<T>>,
19 len: u32,
20 first_free: Option<FreePointer>,
21}
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
25pub struct Index {
26 pub(crate) slot: u32,
27 pub(crate) generation: Generation,
28}
29
30impl Index {
31 pub const DANGLING: Self = Self {
36 slot: u32::MAX,
37 generation: Generation::DANGLING,
38 };
39
40 #[allow(clippy::integer_arithmetic)]
43 pub const fn to_bits(self) -> u64 {
44 ((self.generation.to_u32() as u64) << 32) | (self.slot as u64)
46 }
47
48 #[allow(clippy::integer_arithmetic)]
60 pub const fn from_bits(bits: u64) -> Option<Self> {
61 let generation = match Generation::from_u32((bits >> 32) as u32) {
64 Some(v) => v,
65 None => return None,
66 };
67
68 let slot = bits as u32;
69
70 Some(Self { generation, slot })
71 }
72
73 pub const fn generation(self) -> u32 {
75 self.generation.to_u32()
76 }
77
78 pub const fn slot(self) -> u32 {
81 self.slot
82 }
83}
84
85#[derive(Debug, Clone)]
86pub(crate) enum Entry<T> {
87 Occupied(OccupiedEntry<T>),
88 Empty(EmptyEntry),
89}
90
91impl<T> Entry<T> {
92 fn into_value(self) -> Option<T> {
94 match self {
95 Entry::Occupied(occupied) => Some(occupied.value),
96 Entry::Empty(_) => None,
97 }
98 }
99
100 fn get_value_mut(&mut self, generation: Generation) -> Option<&mut T> {
101 match self {
102 Entry::Occupied(occupied) if occupied.generation == generation => {
103 Some(&mut occupied.value)
104 }
105 _ => None,
106 }
107 }
108
109 fn as_empty(&self) -> Option<&EmptyEntry> {
111 match self {
112 Entry::Empty(empty) => Some(empty),
113 Entry::Occupied(_) => None,
114 }
115 }
116
117 fn as_empty_mut(&mut self) -> Option<&mut EmptyEntry> {
119 match self {
120 Entry::Empty(empty) => Some(empty),
121 Entry::Occupied(_) => None,
122 }
123 }
124}
125
126#[derive(Debug, Clone)]
127pub(crate) struct OccupiedEntry<T> {
128 pub(crate) generation: Generation,
129 pub(crate) value: T,
130}
131
132#[derive(Debug, Clone, Copy)]
133pub(crate) struct EmptyEntry {
134 pub(crate) generation: Generation,
135 pub(crate) next_free: Option<FreePointer>,
136}
137
138impl<T> Arena<T> {
139 pub const fn new() -> Self {
141 Self {
142 storage: Vec::new(),
143 len: 0,
144 first_free: None,
145 }
146 }
147
148 pub fn with_capacity(capacity: usize) -> Self {
151 Self {
152 storage: Vec::with_capacity(capacity),
153 len: 0,
154 first_free: None,
155 }
156 }
157
158 pub const fn len(&self) -> usize {
160 self.len as usize
161 }
162
163 pub fn capacity(&self) -> usize {
166 self.storage.capacity()
167 }
168
169 pub const fn is_empty(&self) -> bool {
171 self.len == 0
172 }
173
174 pub fn insert(&mut self, value: T) -> Index {
177 self.len = self
179 .len
180 .checked_add(1)
181 .unwrap_or_else(|| panic!("Cannot insert more than u32::MAX elements into Arena"));
182
183 if let Some(free_pointer) = self.first_free {
186 let slot = free_pointer.slot();
187 let entry = self.storage.get_mut(slot as usize).unwrap_or_else(|| {
188 unreachable!("first_free pointed past the end of the arena's storage")
189 });
190
191 let empty = entry
192 .as_empty()
193 .unwrap_or_else(|| unreachable!("first_free pointed to an occupied entry"));
194
195 self.first_free = empty.next_free;
198
199 let generation = empty.generation.next();
203 *entry = Entry::Occupied(OccupiedEntry { generation, value });
204
205 Index { slot, generation }
206 } else {
207 let generation = Generation::first();
211 let slot: u32 = self.storage.len().try_into().unwrap_or_else(|_| {
212 unreachable!("Arena storage exceeded what can be represented by a u32")
213 });
214
215 self.storage
216 .push(Entry::Occupied(OccupiedEntry { generation, value }));
217
218 Index { slot, generation }
219 }
220 }
221
222 fn remove_slot_from_free_list(&mut self, slot: u32, new_next_free: Option<FreePointer>) {
225 let mut next_fp = self
228 .first_free
229 .expect("Free entry exists but first_free is None");
230
231 let mut current_slot = None;
237 while next_fp.slot() != slot {
238 current_slot = Some(next_fp.slot());
239 next_fp = self
240 .storage
241 .get(next_fp.slot() as usize)
242 .expect("Empty entry not in storage!")
243 .as_empty()
244 .expect("Entry in free list not actually empty!")
245 .next_free
246 .expect("Hit the end of the free list without finding the target slot!");
247 }
248
249 match current_slot {
252 Some(slot_to_fix) => {
253 self.storage[slot_to_fix as usize]
254 .as_empty_mut()
255 .unwrap()
256 .next_free = new_next_free
257 }
258 None => self.first_free = new_next_free,
259 }
260 }
261
262 #[inline]
264 fn insert_at_inner(
265 &mut self,
266 slot: u32,
267 generation: Option<Generation>,
268 value: T,
269 ) -> (Index, Option<T>) {
270 let (index, old_value) = match self.storage.get_mut(slot as usize) {
280 Some(Entry::Empty(empty)) => {
281 let generation = generation.unwrap_or_else(|| empty.generation.next());
282 let new_next_free = empty.next_free;
285 self.remove_slot_from_free_list(slot, new_next_free);
286 self.storage[slot as usize] = Entry::Occupied(OccupiedEntry { generation, value });
287
288 (Index { slot, generation }, None)
289 }
290 Some(Entry::Occupied(occupied)) => {
291 occupied.generation = generation.unwrap_or_else(|| occupied.generation.next());
292 let generation = occupied.generation;
293 let old_value = replace(&mut occupied.value, value);
294
295 (Index { slot, generation }, Some(old_value))
296 }
297 None => {
298 let mut first_free = self.first_free;
299 while self.storage.len() < slot as usize {
300 let new_slot: u32 = self.storage.len().try_into().unwrap_or_else(|_| {
301 unreachable!("Arena storage exceeded what can be represented by a u32")
302 });
303
304 self.storage.push(Entry::Empty(EmptyEntry {
305 generation: Generation::first(),
306 next_free: first_free,
307 }));
308
309 first_free = Some(FreePointer::from_slot(new_slot));
310 }
311
312 self.first_free = first_free;
313 let generation = generation.unwrap_or_else(Generation::first);
314 self.storage
315 .push(Entry::Occupied(OccupiedEntry { generation, value }));
316
317 (Index { slot, generation }, None)
318 }
319 };
320
321 if old_value.is_none() {
324 self.len = self
325 .len
326 .checked_add(1)
327 .unwrap_or_else(|| panic!("Cannot insert more than u32::MAX elements into Arena"));
328 }
329
330 (index, old_value)
331 }
332
333 pub fn insert_at(&mut self, index: Index, value: T) -> Option<T> {
344 self.insert_at_inner(index.slot, Some(index.generation), value)
345 .1
346 }
347
348 pub fn insert_at_slot(&mut self, slot: u32, value: T) -> (Index, Option<T>) {
352 self.insert_at_inner(slot, None, value)
353 }
354
355 pub fn contains(&self, index: Index) -> bool {
357 match self.storage.get(index.slot as usize) {
358 Some(Entry::Occupied(occupied)) if occupied.generation == index.generation => true,
359 _ => false,
360 }
361 }
362
363 pub fn contains_slot(&self, slot: u32) -> Option<Index> {
367 match self.storage.get(slot as usize) {
368 Some(Entry::Occupied(occupied)) => Some(Index {
369 slot,
370 generation: occupied.generation,
371 }),
372 _ => None,
373 }
374 }
375
376 pub fn get(&self, index: Index) -> Option<&T> {
379 match self.storage.get(index.slot as usize) {
380 Some(Entry::Occupied(occupied)) if occupied.generation == index.generation => {
381 Some(&occupied.value)
382 }
383 _ => None,
384 }
385 }
386
387 pub fn get_mut(&mut self, index: Index) -> Option<&mut T> {
390 match self.storage.get_mut(index.slot as usize) {
391 Some(entry) => entry.get_value_mut(index.generation),
392 _ => None,
393 }
394 }
395
396 pub fn get2_mut(&mut self, index1: Index, index2: Index) -> (Option<&mut T>, Option<&mut T>) {
405 if index1 == index2 {
406 panic!("Arena::get2_mut is called with two identical indices");
407 }
408
409 if index1.slot == index2.slot {
412 if self.get(index1).is_some() {
415 return (self.get_mut(index1), None);
416 } else {
417 return (None, self.get_mut(index2));
418 }
419 }
420
421 let (entry1, entry2) = if index1.slot > index2.slot {
424 let (slice1, slice2) = self.storage.split_at_mut(index1.slot as usize);
425 (slice2.get_mut(0), slice1.get_mut(index2.slot as usize))
426 } else {
427 let (slice1, slice2) = self.storage.split_at_mut(index2.slot as usize);
428 (slice1.get_mut(index1.slot as usize), slice2.get_mut(0))
429 };
430
431 (
432 entry1.and_then(|e| e.get_value_mut(index1.generation)),
433 entry2.and_then(|e| e.get_value_mut(index2.generation)),
434 )
435 }
436
437 pub fn remove(&mut self, index: Index) -> Option<T> {
440 let entry = self.storage.get_mut(index.slot as usize)?;
441
442 match entry {
443 Entry::Occupied(occupied) if occupied.generation == index.generation => {
444 let new_entry = Entry::Empty(EmptyEntry {
448 generation: occupied.generation,
449 next_free: self.first_free,
450 });
451
452 let old_entry = replace(entry, new_entry);
456 let value = old_entry.into_value().unwrap_or_else(|| unreachable!());
457
458 self.first_free = Some(FreePointer::from_slot(index.slot));
462
463 self.len = self.len.checked_sub(1).unwrap_or_else(|| unreachable!());
464
465 Some(value)
466 }
467 _ => None,
468 }
469 }
470
471 pub fn invalidate(&mut self, index: Index) -> Option<Index> {
475 let entry = self.storage.get_mut(index.slot as usize)?;
476
477 match entry {
478 Entry::Occupied(occupied) if occupied.generation == index.generation => {
479 occupied.generation = occupied.generation.next();
480
481 Some(Index {
482 generation: occupied.generation,
483 ..index
484 })
485 }
486 _ => None,
487 }
488 }
489
490 pub fn get_by_slot(&self, slot: u32) -> Option<(Index, &T)> {
494 match self.storage.get(slot as usize) {
495 Some(Entry::Occupied(occupied)) => {
496 let index = Index {
497 slot,
498 generation: occupied.generation,
499 };
500 Some((index, &occupied.value))
501 }
502 _ => None,
503 }
504 }
505
506 pub fn get_by_slot_mut(&mut self, slot: u32) -> Option<(Index, &mut T)> {
510 match self.storage.get_mut(slot as usize) {
511 Some(Entry::Occupied(occupied)) => {
512 let index = Index {
513 slot,
514 generation: occupied.generation,
515 };
516 Some((index, &mut occupied.value))
517 }
518 _ => None,
519 }
520 }
521
522 pub fn remove_by_slot(&mut self, slot: u32) -> Option<(Index, T)> {
525 let entry = self.storage.get_mut(slot as usize)?;
526
527 match entry {
528 Entry::Occupied(occupied) => {
529 let index = Index {
531 generation: occupied.generation,
532 slot,
533 };
534
535 let next_entry = Entry::Empty(EmptyEntry {
539 generation: occupied.generation,
540 next_free: self.first_free,
541 });
542
543 let old_entry = replace(entry, next_entry);
545 let value = old_entry.into_value().unwrap_or_else(|| unreachable!());
546
547 self.first_free = Some(FreePointer::from_slot(slot));
550
551 self.len = self.len.checked_sub(1).unwrap_or_else(|| unreachable!());
552
553 Some((index, value))
554 }
555 _ => None,
556 }
557 }
558
559 pub fn clear(&mut self) {
561 self.drain().for_each(drop);
562 }
563
564 pub fn iter(&self) -> Iter<'_, T> {
568 Iter {
569 inner: self.storage.iter(),
570 slot: 0,
571 len: self.len,
572 }
573 }
574
575 pub fn iter_mut(&mut self) -> IterMut<'_, T> {
580 IterMut {
581 inner: self.storage.iter_mut(),
582 slot: 0,
583 len: self.len,
584 }
585 }
586
587 pub fn drain(&mut self) -> Drain<'_, T> {
595 Drain {
596 arena: self,
597 slot: 0,
598 }
599 }
600
601 pub fn retain<F: FnMut(Index, &mut T) -> bool>(&mut self, mut f: F) {
603 for (i, entry) in self.storage.iter_mut().enumerate() {
604 if let Entry::Occupied(occupied) = entry {
605 let index = Index {
606 slot: i as u32,
607 generation: occupied.generation,
608 };
609
610 if !f(index, &mut occupied.value) {
611 *entry = Entry::Empty(EmptyEntry {
615 generation: occupied.generation,
616 next_free: self.first_free,
617 });
618
619 self.first_free = Some(FreePointer::from_slot(index.slot));
623
624 self.len = self.len.checked_sub(1).unwrap_or_else(|| unreachable!());
627 }
628 }
629 }
630 }
631}
632
633impl<T> Default for Arena<T> {
634 fn default() -> Self {
635 Arena::new()
636 }
637}
638
639impl<T> IntoIterator for Arena<T> {
640 type Item = (Index, T);
641 type IntoIter = IntoIter<T>;
642
643 fn into_iter(self) -> Self::IntoIter {
644 IntoIter {
645 arena: self,
646 slot: 0,
647 }
648 }
649}
650
651impl<'a, T> IntoIterator for &'a Arena<T> {
652 type Item = (Index, &'a T);
653 type IntoIter = Iter<'a, T>;
654
655 fn into_iter(self) -> Self::IntoIter {
656 self.iter()
657 }
658}
659
660impl<'a, T> IntoIterator for &'a mut Arena<T> {
661 type Item = (Index, &'a mut T);
662 type IntoIter = IterMut<'a, T>;
663
664 fn into_iter(self) -> Self::IntoIter {
665 self.iter_mut()
666 }
667}
668
669impl<T> ops::Index<Index> for Arena<T> {
670 type Output = T;
671
672 fn index(&self, index: Index) -> &Self::Output {
673 self.get(index)
674 .unwrap_or_else(|| panic!("No entry at index {:?}", index))
675 }
676}
677
678impl<T> ops::IndexMut<Index> for Arena<T> {
679 fn index_mut(&mut self, index: Index) -> &mut Self::Output {
680 self.get_mut(index)
681 .unwrap_or_else(|| panic!("No entry at index {:?}", index))
682 }
683}
684
685#[cfg(test)]
686mod test {
687 use crate::free_pointer::FreePointer;
688
689 use super::{Arena, Generation, Index};
690
691 use core::mem::size_of;
692
693 #[test]
694 fn size_of_index() {
695 assert_eq!(size_of::<Index>(), 8);
696 assert_eq!(size_of::<Option<Index>>(), 8);
697 }
698
699 #[test]
700 fn new() {
701 let arena: Arena<u32> = Arena::new();
702 assert_eq!(arena.len(), 0);
703 assert_eq!(arena.capacity(), 0);
704 }
705
706 #[test]
707 fn with_capacity() {
708 let arena: Arena<u32> = Arena::with_capacity(8);
709 assert_eq!(arena.len(), 0);
710 assert_eq!(arena.capacity(), 8);
711 }
712
713 #[test]
714 fn insert_and_get() {
715 let mut arena = Arena::new();
716
717 let one = arena.insert(1);
718 assert_eq!(arena.len(), 1);
719 assert_eq!(arena.get(one), Some(&1));
720
721 let two = arena.insert(2);
722 assert_eq!(arena.len(), 2);
723 assert_eq!(arena.get(one), Some(&1));
724 assert_eq!(arena.get(two), Some(&2));
725 }
726
727 #[test]
728 fn insert_remove_get() {
729 let mut arena = Arena::new();
730 let one = arena.insert(1);
731
732 let two = arena.insert(2);
733 assert_eq!(arena.len(), 2);
734 assert!(arena.contains(two));
735 assert_eq!(arena.remove(two), Some(2));
736 assert!(!arena.contains(two));
737
738 let three = arena.insert(3);
739 assert_eq!(arena.len(), 2);
740 assert_eq!(arena.get(one), Some(&1));
741 assert_eq!(arena.get(three), Some(&3));
742 assert_eq!(arena.get(two), None);
743 }
744
745 #[test]
746 fn insert_remove_get_by_slot() {
747 let mut arena = Arena::new();
748 let one = arena.insert(1);
749
750 let two = arena.insert(2);
751 assert_eq!(arena.len(), 2);
752 assert!(arena.contains(two));
753 assert_eq!(arena.remove_by_slot(two.slot()), Some((two, 2)));
754 assert!(!arena.contains(two));
755 assert_eq!(arena.get_by_slot(two.slot()), None);
756
757 let three = arena.insert(3);
758 assert_eq!(arena.len(), 2);
759 assert_eq!(arena.get(one), Some(&1));
760 assert_eq!(arena.get(three), Some(&3));
761 assert_eq!(arena.get(two), None);
762 assert_eq!(arena.get_by_slot(two.slot()), Some((three, &3)));
763 }
764
765 #[test]
766 fn insert_at() {
767 let mut arena = Arena::new();
768 let index = Index {
770 slot: 42,
771 generation: Generation::from_u32(78).unwrap(),
772 };
773 arena.insert_at(index, 5);
774 assert_eq!(arena.len(), 1);
775 assert_eq!(arena.get(index), Some(&5));
776 assert_eq!(arena.get_by_slot(42), Some((index, &5)));
777 }
778
779 #[test]
780 fn insert_at_first_slot() {
781 let mut arena = Arena::new();
782 let index = Index {
784 slot: 0,
785 generation: Generation::from_u32(3).unwrap(),
786 };
787 arena.insert_at(index, 5);
788 assert_eq!(arena.len(), 1);
789 assert_eq!(arena.get(index), Some(&5));
790 assert_eq!(arena.get_by_slot(0), Some((index, &5)));
791 }
792
793 #[test]
794 fn insert_at_slot() {
795 let mut arena = Arena::new();
796
797 let (index, _) = arena.insert_at_slot(42, 5);
798 assert_eq!(arena.len(), 1);
799 assert_eq!(arena.get(index), Some(&5));
800 assert_eq!(arena.get_by_slot(42), Some((index, &5)));
801 }
802
803 #[test]
804 fn insert_at_middle() {
805 let mut arena = Arena::new();
806 arena.insert_at_slot(4, 50);
807 arena.insert_at_slot(2, 40);
808
809 let empty = arena.storage.get(3).unwrap().as_empty().unwrap();
810 if empty.next_free != Some(FreePointer::from_slot(1)) {
811 panic!("Invalid free list: {:#?}", arena);
812 }
813 }
814
815 #[test]
816 fn get_mut() {
817 let mut arena = Arena::new();
818 let foo = arena.insert(5);
819
820 let handle = arena.get_mut(foo).unwrap();
821 *handle = 6;
822
823 assert_eq!(arena.get(foo), Some(&6));
824 }
825
826 #[test]
827 fn get2_mut() {
828 let mut arena = Arena::new();
829 let foo = arena.insert(100);
830 let bar = arena.insert(500);
831
832 let (foo_handle, bar_handle) = arena.get2_mut(foo, bar);
833 let foo_handle = foo_handle.unwrap();
834 let bar_handle = bar_handle.unwrap();
835 *foo_handle = 105;
836 *bar_handle = 505;
837
838 assert_eq!(arena.get(foo), Some(&105));
839 assert_eq!(arena.get(bar), Some(&505));
840 }
841
842 #[test]
843 fn get2_mut_reversed_order() {
844 let mut arena = Arena::new();
845 let foo = arena.insert(100);
846 let bar = arena.insert(500);
847
848 let (bar_handle, foo_handle) = arena.get2_mut(bar, foo);
849 let foo_handle = foo_handle.unwrap();
850 let bar_handle = bar_handle.unwrap();
851 *foo_handle = 105;
852 *bar_handle = 505;
853
854 assert_eq!(arena.get(foo), Some(&105));
855 assert_eq!(arena.get(bar), Some(&505));
856 }
857
858 #[test]
859 fn get2_mut_non_exist_handle() {
860 let mut arena = Arena::new();
861 let foo = arena.insert(100);
862 let bar = arena.insert(500);
863 arena.remove(bar);
864
865 let (bar_handle, foo_handle) = arena.get2_mut(bar, foo);
866 let foo_handle = foo_handle.unwrap();
867 assert!(bar_handle.is_none());
868 *foo_handle = 105;
869
870 assert_eq!(arena.get(foo), Some(&105));
871 }
872
873 #[test]
874 fn get2_mut_same_slot_different_generation() {
875 let mut arena = Arena::new();
876 let foo = arena.insert(100);
877 let mut foo1 = foo;
878 foo1.generation = foo1.generation.next();
879
880 let (foo_handle, foo1_handle) = arena.get2_mut(foo, foo1);
881 assert!(foo_handle.is_some());
882 assert!(foo1_handle.is_none());
883 }
884
885 #[test]
886 #[should_panic]
887 fn get2_mut_panics() {
888 let mut arena = Arena::new();
889 let foo = arena.insert(100);
890
891 arena.get2_mut(foo, foo);
892 }
893
894 #[test]
895 fn insert_remove_insert_capacity() {
896 let mut arena = Arena::with_capacity(2);
897 assert_eq!(arena.capacity(), 2);
898
899 let a = arena.insert("a");
900 let b = arena.insert("b");
901 assert_eq!(arena.len(), 2);
902 assert_eq!(arena.capacity(), 2);
903
904 arena.remove(a);
905 arena.remove(b);
906 assert_eq!(arena.len(), 0);
907 assert_eq!(arena.capacity(), 2);
908
909 let _a2 = arena.insert("a2");
910 let _b2 = arena.insert("b2");
911 assert_eq!(arena.len(), 2);
912 assert_eq!(arena.capacity(), 2);
913 }
914
915 #[test]
916 fn invalidate() {
917 let mut arena = Arena::new();
918
919 let a = arena.insert("a");
920 assert_eq!(arena.get(a), Some(&"a"));
921
922 let new_a = arena.invalidate(a).unwrap();
923 assert_eq!(arena.get(a), None);
924 assert_eq!(arena.get(new_a), Some(&"a"));
925 }
926
927 #[test]
928 fn retain() {
929 let mut arena = Arena::new();
930
931 for i in 0..100 {
932 arena.insert(i);
933 }
934
935 arena.retain(|_, &mut i| i % 2 == 1);
936
937 for (_, i) in arena.iter() {
938 assert_eq!(i % 2, 1);
939 }
940
941 assert_eq!(arena.len(), 50);
942 }
943
944 #[test]
945 fn index_bits_roundtrip() {
946 let index = Index::from_bits(0x1BAD_CAFE_DEAD_BEEF).unwrap();
947 assert_eq!(index.to_bits(), 0x1BAD_CAFE_DEAD_BEEF);
948 }
949
950 #[test]
951 fn index_bits_none_on_zero_generation() {
952 let index = Index::from_bits(0x0000_0000_DEAD_BEEF);
953 assert_eq!(index, None);
954 }
955}