tess2_rust/
bucketalloc.rs1pub struct BucketAlloc<T> {
13 items: Vec<Option<T>>,
14 free_list: Vec<u32>,
15}
16
17impl<T: Default> BucketAlloc<T> {
18 pub fn new() -> Self {
19 Self {
20 items: Vec::new(),
21 free_list: Vec::new(),
22 }
23 }
24
25 pub fn alloc(&mut self) -> u32 {
27 if let Some(idx) = self.free_list.pop() {
28 self.items[idx as usize] = Some(T::default());
29 idx
30 } else {
31 let idx = self.items.len() as u32;
32 self.items.push(Some(T::default()));
33 idx
34 }
35 }
36
37 pub fn free(&mut self, idx: u32) {
39 self.items[idx as usize] = None;
40 self.free_list.push(idx);
41 }
42
43 pub fn get(&self, idx: u32) -> Option<&T> {
44 self.items.get(idx as usize)?.as_ref()
45 }
46
47 pub fn get_mut(&mut self, idx: u32) -> Option<&mut T> {
48 self.items.get_mut(idx as usize)?.as_mut()
49 }
50}
51
52impl<T: Default> Default for BucketAlloc<T> {
53 fn default() -> Self {
54 Self::new()
55 }
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61
62 #[test]
63 fn alloc_and_free() {
64 let mut ba: BucketAlloc<u32> = BucketAlloc::new();
65 let a = ba.alloc();
66 let b = ba.alloc();
67 assert_ne!(a, b);
68 ba.free(a);
69 let c = ba.alloc();
70 assert_eq!(c, a);
72 }
73
74 #[test]
75 fn get_returns_default() {
76 let mut ba: BucketAlloc<i32> = BucketAlloc::new();
77 let idx = ba.alloc();
78 assert_eq!(*ba.get(idx).unwrap(), 0);
79 }
80
81 #[test]
82 fn get_after_free_returns_none() {
83 let mut ba: BucketAlloc<i32> = BucketAlloc::new();
84 let idx = ba.alloc();
85 ba.free(idx);
86 assert!(ba.get(idx).is_none());
87 }
88}