oxihuman_core/
object_arena.rs1#![allow(dead_code)]
4
5pub type Generation = u32;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub struct ArenaHandle {
14 pub index: usize,
15 pub generation: Generation,
16}
17
18pub struct ObjectArena<T> {
20 data: Vec<T>,
21 generation: Generation,
22}
23
24impl<T> ObjectArena<T> {
25 pub fn with_capacity(cap: usize) -> Self {
27 Self {
28 data: Vec::with_capacity(cap),
29 generation: 0,
30 }
31 }
32
33 pub fn alloc(&mut self, value: T) -> ArenaHandle {
35 let index = self.data.len();
36 self.data.push(value);
37 ArenaHandle {
38 index,
39 generation: self.generation,
40 }
41 }
42
43 pub fn get(&self, handle: ArenaHandle) -> Option<&T> {
45 if handle.generation == self.generation {
46 self.data.get(handle.index)
47 } else {
48 None
49 }
50 }
51
52 pub fn len(&self) -> usize {
54 self.data.len()
55 }
56
57 pub fn is_empty(&self) -> bool {
59 self.data.is_empty()
60 }
61
62 pub fn reset(&mut self) {
64 self.data.clear();
65 self.generation = self.generation.wrapping_add(1);
66 }
67
68 pub fn generation(&self) -> Generation {
70 self.generation
71 }
72}
73
74pub fn new_object_arena<T>(cap: usize) -> ObjectArena<T> {
76 ObjectArena::with_capacity(cap)
77}
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82
83 #[test]
84 fn test_alloc_and_get() {
85 let mut arena: ObjectArena<i32> = ObjectArena::with_capacity(8);
86 let h = arena.alloc(42);
87 assert_eq!(arena.get(h), Some(&42)); }
89
90 #[test]
91 fn test_reset_invalidates_handles() {
92 let mut arena: ObjectArena<i32> = ObjectArena::with_capacity(8);
93 let h = arena.alloc(1);
94 arena.reset();
95 assert_eq!(arena.get(h), None); }
97
98 #[test]
99 fn test_len_after_alloc() {
100 let mut arena: ObjectArena<u8> = ObjectArena::with_capacity(4);
101 arena.alloc(1);
102 arena.alloc(2);
103 assert_eq!(arena.len(), 2); }
105
106 #[test]
107 fn test_is_empty_initial() {
108 let arena: ObjectArena<i32> = ObjectArena::with_capacity(4);
109 assert!(arena.is_empty()); }
111
112 #[test]
113 fn test_is_empty_after_reset() {
114 let mut arena: ObjectArena<i32> = ObjectArena::with_capacity(4);
115 arena.alloc(5);
116 arena.reset();
117 assert!(arena.is_empty()); }
119
120 #[test]
121 fn test_generation_increments() {
122 let mut arena: ObjectArena<i32> = ObjectArena::with_capacity(4);
123 let g0 = arena.generation();
124 arena.reset();
125 assert_eq!(arena.generation(), g0 + 1); }
127
128 #[test]
129 fn test_multiple_allocs() {
130 let mut arena: ObjectArena<f32> = ObjectArena::with_capacity(16);
131 let handles: Vec<_> = (0..8).map(|i| arena.alloc(i as f32)).collect();
132 for (i, h) in handles.iter().enumerate() {
133 assert_eq!(arena.get(*h), Some(&(i as f32))); }
135 }
136
137 #[test]
138 fn test_new_helper() {
139 let arena = new_object_arena::<u64>(32);
140 assert!(arena.is_empty()); }
142
143 #[test]
144 fn test_handle_index() {
145 let mut arena: ObjectArena<i32> = ObjectArena::with_capacity(4);
146 let h = arena.alloc(7);
147 assert_eq!(h.index, 0); }
149}