1use crate::ChildIndex;
2
3use slab::Slab;
4
5#[derive(Clone, Debug)]
11pub struct NodeAllocator<T, const CHILDREN: usize> {
12 pointers: Slab<[AllocPtr; CHILDREN]>,
14 values: Slab<T>,
16}
17
18pub type AllocPtr = u32;
20
21pub const EMPTY_ALLOC_PTR: AllocPtr = AllocPtr::MAX;
23
24impl<T, const CHILDREN: usize> Default for NodeAllocator<T, CHILDREN> {
25 fn default() -> Self {
26 Self {
27 pointers: Default::default(),
28 values: Default::default(),
29 }
30 }
31}
32
33impl<T, const CHILDREN: usize> NodeAllocator<T, CHILDREN> {
34 #[inline]
35 pub fn insert_leaf(&mut self, value: T) -> AllocPtr {
36 self.values.insert(value) as AllocPtr
37 }
38
39 #[inline]
40 pub fn insert_branch(&mut self, value: T) -> AllocPtr {
41 let ptr = self.values.insert(value);
42 let pointer_entry = self.pointers.vacant_entry();
43 debug_assert_eq!(ptr, pointer_entry.key());
44 pointer_entry.insert([EMPTY_ALLOC_PTR; CHILDREN]);
45 ptr as AllocPtr
46 }
47
48 #[inline]
49 pub fn remove(&mut self, ptr: AllocPtr) -> (Option<T>, Option<[AllocPtr; CHILDREN]>) {
50 (
51 self.values.try_remove(ptr as usize),
52 self.pointers.try_remove(ptr as usize),
53 )
54 }
55
56 #[inline]
57 pub fn contains_node(&self, ptr: AllocPtr) -> bool {
58 self.values.contains(ptr as usize)
60 }
61
62 #[inline]
63 pub unsafe fn get_value_unchecked(&self, ptr: AllocPtr) -> &T {
64 self.values.get_unchecked(ptr as usize)
65 }
66
67 #[inline]
68 pub unsafe fn get_value_unchecked_mut(&mut self, ptr: AllocPtr) -> &mut T {
69 self.values.get_unchecked_mut(ptr as usize)
70 }
71
72 #[inline]
73 pub fn get_children_mut_or_panic(&mut self, ptr: AllocPtr) -> &mut [AllocPtr; CHILDREN] {
74 self.get_children_mut(ptr).unwrap_or_else(|| {
75 panic!(
76 "Tried inserting children of {:?} which has no child pointers",
77 ptr,
78 )
79 })
80 }
81
82 #[inline]
83 pub fn get_value(&self, ptr: AllocPtr) -> Option<&T> {
84 self.values.get(ptr as usize)
85 }
86
87 #[inline]
88 pub fn get_value_mut(&mut self, ptr: AllocPtr) -> Option<&mut T> {
89 self.values.get_mut(ptr as usize)
90 }
91
92 #[inline]
93 pub fn get_children(&self, ptr: AllocPtr) -> Option<&[AllocPtr; CHILDREN]> {
94 self.pointers.get(ptr as usize)
95 }
96
97 #[inline]
98 pub fn get_children_mut(&mut self, ptr: AllocPtr) -> Option<&mut [AllocPtr; CHILDREN]> {
99 self.pointers.get_mut(ptr as usize)
100 }
101
102 #[inline]
103 pub fn set_child_pointer(
104 &mut self,
105 parent_ptr: AllocPtr,
106 child_index: ChildIndex,
107 child_ptr: AllocPtr,
108 ) {
109 if let Some(children) = self.get_children_mut(parent_ptr) {
110 children[child_index as usize] = child_ptr;
111 }
112 }
113
114 #[inline]
115 pub fn unlink_child(&mut self, parent_ptr: AllocPtr, child_index: ChildIndex) {
116 self.set_child_pointer(parent_ptr, child_index, EMPTY_ALLOC_PTR)
117 }
118}