traaains/utils/alloc_map/
stack.rs1use crate::utils::interval_tree::{
2 IntervalBitmap, interval_to_bitfields, interval_to_internal, leaves_to_depth, left_child,
3 right_child,
4};
5
6#[derive(Clone, Default)]
9pub struct AllocMap<const N: usize>(IntervalBitmap<N>)
10where
11 [(); interval_to_bitfields(N)]:;
12
13impl<const N: usize> AllocMap<N>
14where
15 [(); interval_to_bitfields(N)]:,
16{
17 fn find_first_free(&self) -> Option<usize> {
19 if self.0.get_at_tree(0) {
21 return None;
22 }
23
24 let mut curr_index = 0;
26 for _ in 0..leaves_to_depth(N) {
27 let left_child = left_child(curr_index);
28 curr_index = if !self.0.get_at_tree(left_child) {
29 left_child
30 } else {
31 let right_child = right_child(curr_index);
32 debug_assert!(
33 !self.0.get_at_tree(right_child),
34 "both children allocated while parent is not"
35 );
36 right_child
37 };
38 }
39
40 Some(curr_index - interval_to_internal(N))
41 }
42
43 pub fn allocate(&mut self) -> Option<usize> {
45 self.find_first_free().inspect(|index| {
46 self.0.set_at(*index, true);
47 })
48 }
49
50 pub fn deallocate(&mut self, index: usize) {
52 self.0.set_at(index, false);
53 }
54
55 pub fn is_allocated(&mut self, index: usize) -> bool {
56 self.0.get_at(index)
57 }
58
59 pub fn has_free(&self) -> bool {
60 self.find_first_free().is_some()
61 }
62}
63
64#[cfg(test)]
65mod tests {
66 use crate::utils::alloc_map::AllocMap;
67
68 #[test]
69 fn alloc_map() {
70 let mut map = AllocMap::<2>::default();
71 assert_eq!(map.allocate(), Some(0));
72 assert_eq!(map.allocate(), Some(1));
73 assert_eq!(map.allocate(), None);
74 map.deallocate(0);
75 assert_eq!(map.allocate(), Some(0));
76 }
77}