1use std::fmt;
29use std::marker::PhantomData;
30
31#[allow(dead_code)]
33const CACHE_LINE_SIZE: usize = 64;
34
35#[derive(Clone, Debug)]
41pub struct Slot<T> {
42 pub data: Option<T>,
44 pub generation: u32,
46}
47
48impl<T> Slot<T> {
49 pub fn new(data: T, generation: u32) -> Self {
51 Self {
52 data: Some(data),
53 generation,
54 }
55 }
56
57 #[inline]
59 pub fn is_occupied(&self) -> bool {
60 self.data.is_some()
61 }
62
63 #[inline]
65 pub fn data(&self) -> Option<&T> {
66 self.data.as_ref()
67 }
68
69 #[inline]
71 pub fn data_mut(&mut self) -> Option<&mut T> {
72 self.data.as_mut()
73 }
74
75 #[inline]
77 pub fn replace(&mut self, new_data: T) -> Option<T> {
78 self.data.replace(new_data)
79 }
80
81 #[inline]
83 pub fn clear(&mut self) -> Option<T> {
84 self.data.take()
85 }
86}
87
88pub struct Arena<T> {
110 slots: Vec<Slot<T>>,
112 free_list: Vec<usize>,
114 _marker: PhantomData<T>,
115}
116
117impl<T> fmt::Debug for Arena<T> {
118 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
119 f.debug_struct("Arena")
120 .field("len", &self.len())
121 .field("capacity", &self.capacity())
122 .field("free_list_len", &self.free_list.len())
123 .finish()
124 }
125}
126
127impl<T> Arena<T> {
128 pub fn new() -> Self {
130 Self {
131 slots: Vec::new(),
132 free_list: Vec::new(),
133 _marker: PhantomData,
134 }
135 }
136
137 pub fn with_capacity(capacity: usize) -> Self {
139 Self {
140 slots: Vec::with_capacity(capacity),
141 free_list: Vec::with_capacity(capacity),
142 _marker: PhantomData,
143 }
144 }
145
146 #[inline]
153 pub fn allocate(&mut self, value: T) -> (usize, u32) {
154 if let Some(index) = self.free_list.pop() {
155 let slot = &mut self.slots[index];
157 let new_generation = slot.generation.wrapping_add(1);
158 *slot = Slot::new(value, new_generation);
159 (index, new_generation)
160 } else {
161 let index = self.slots.len();
163 let generation = 1u32;
164 self.slots.push(Slot::new(value, generation));
165 (index, generation)
166 }
167 }
168
169 #[inline]
181 pub fn deallocate(&mut self, index: usize, generation: u32) -> Option<T> {
182 if index >= self.slots.len() {
183 return None;
184 }
185
186 let slot = &mut self.slots[index];
187 if slot.generation != generation {
188 return None; }
190
191 let value = slot.data.take()?;
192 self.free_list.push(index);
193 Some(value)
194 }
195
196 #[inline]
203 pub fn get(&self, index: usize, generation: u32) -> Option<&T> {
204 self.slots
205 .get(index)
206 .filter(|slot| slot.generation == generation && slot.is_occupied())
207 .and_then(|slot| slot.data())
208 }
209
210 #[inline]
212 pub fn get_mut(&mut self, index: usize, generation: u32) -> Option<&mut T> {
213 self.slots
214 .get_mut(index)
215 .filter(|slot| slot.generation == generation && slot.is_occupied())
216 .and_then(|slot| slot.data_mut())
217 }
218
219 #[inline]
221 pub fn is_valid(&self, index: usize, generation: u32) -> bool {
222 self.slots
223 .get(index)
224 .is_some_and(|slot| slot.generation == generation && slot.is_occupied())
225 }
226
227 #[inline]
229 pub fn get_slot(&self, index: usize) -> Option<&Slot<T>> {
230 self.slots.get(index)
231 }
232
233 #[inline]
235 pub fn get_slot_mut(&mut self, index: usize) -> Option<&mut Slot<T>> {
236 self.slots.get_mut(index)
237 }
238
239 #[inline]
241 pub fn clear(&mut self) {
242 for slot in &mut self.slots {
243 slot.data = None;
244 }
245 self.free_list.clear();
246 for i in 0..self.slots.len() {
247 self.free_list.push(i);
248 }
249 }
250
251 #[inline]
253 pub fn drain(&mut self) {
254 self.slots.clear();
255 self.free_list.clear();
256 }
257
258 #[inline]
260 pub fn len(&self) -> usize {
261 self.slots.len() - self.free_list.len()
262 }
263
264 #[inline]
266 pub fn is_empty(&self) -> bool {
267 self.len() == 0
268 }
269
270 #[inline]
272 pub fn capacity(&self) -> usize {
273 self.slots.capacity()
274 }
275
276 #[inline]
278 pub fn num_slots(&self) -> usize {
279 self.slots.len()
280 }
281
282 #[inline]
284 pub fn num_free(&self) -> usize {
285 self.free_list.len()
286 }
287
288 #[inline]
290 pub fn reserve(&mut self, additional: usize) {
291 self.slots.reserve(additional);
292 self.free_list.reserve(additional);
293 }
294
295 pub fn shrink_to_fit(&mut self) {
299 self.free_list.shrink_to_fit();
300 self.slots.shrink_to_fit();
301 }
302
303 pub fn iter(&self) -> impl Iterator<Item = (usize, u32, &T)> {
305 self.slots.iter().enumerate().filter_map(|(idx, slot)| {
306 if slot.is_occupied() {
307 Some((idx, slot.generation, slot.data.as_ref().unwrap()))
308 } else {
309 None
310 }
311 })
312 }
313
314 pub fn iter_all(&self) -> impl Iterator<Item = (usize, &Slot<T>)> {
316 self.slots.iter().enumerate()
317 }
318}
319
320impl<T> Default for Arena<T> {
321 fn default() -> Self {
322 Self::new()
323 }
324}
325
326#[cfg(test)]
327mod tests {
328 use super::*;
329
330 #[test]
331 fn test_arena_allocate() {
332 let mut arena = Arena::new();
333 let (idx, generation) = arena.allocate(42);
334 assert_eq!(arena.get(idx, generation), Some(&42));
335 assert_eq!(generation, 1);
336 }
337
338 #[test]
339 fn test_arena_deallocate() {
340 let mut arena = Arena::new();
341 let (idx, generation) = arena.allocate(42);
342 let value = arena.deallocate(idx, generation);
343 assert_eq!(value, Some(42));
344 assert_eq!(arena.get(idx, generation), None);
345 }
346
347 #[test]
348 fn test_arena_reuse() {
349 let mut arena = Arena::new();
350 let (idx1, gen1) = arena.allocate(1);
351 let _ = arena.deallocate(idx1, gen1);
352 let (idx2, gen2) = arena.allocate(2);
353
354 assert_eq!(idx2, idx1);
356 assert_eq!(gen2, gen1 + 1);
358 assert!(arena.get(idx2, gen2).is_some());
359 assert!(arena.get(idx2, gen1).is_none());
360 }
361
362 #[test]
363 fn test_arena_is_valid() {
364 let mut arena = Arena::new();
365 let (idx, generation) = arena.allocate(42);
366
367 assert!(arena.is_valid(idx, generation));
368 assert!(!arena.is_valid(idx, generation + 1)); assert!(!arena.is_valid(idx + 1, generation)); arena.deallocate(idx, generation);
372 assert!(!arena.is_valid(idx, generation)); }
374
375 #[test]
376 fn test_arena_len_and_capacity() {
377 let mut arena = Arena::with_capacity(10);
378 assert_eq!(arena.len(), 0);
379 assert!(arena.is_empty());
380 assert!(arena.capacity() >= 10);
381
382 let (idx, generation) = arena.allocate(1);
383 assert_eq!(arena.len(), 1);
384 assert!(!arena.is_empty());
385
386 arena.deallocate(idx, generation);
387 assert_eq!(arena.len(), 0);
388 }
389
390 #[test]
391 fn test_arena_clear() {
392 let mut arena = Arena::new();
393 let (idx1, _) = arena.allocate(1);
394 let (idx2, _) = arena.allocate(2);
395
396 arena.clear();
397
398 assert!(arena.is_empty());
399 assert!(!arena.is_valid(idx1, 1));
400 assert!(!arena.is_valid(idx2, 1));
401 }
402
403 #[test]
404 fn test_arena_iter() {
405 let mut arena = Arena::new();
406 let (idx1, gen1) = arena.allocate(1);
407 let (idx2, gen2) = arena.allocate(2);
408 let (idx3, gen3) = arena.allocate(3);
409
410 arena.deallocate(idx2, gen2);
411
412 let items: Vec<_> = arena.iter().collect();
413 assert_eq!(items.len(), 2);
414 assert!(items
415 .iter()
416 .any(|(i, g, v)| *i == idx1 && *g == gen1 && **v == 1));
417 assert!(items
418 .iter()
419 .any(|(i, g, v)| *i == idx3 && *g == gen3 && **v == 3));
420 }
421
422 #[test]
423 fn test_arena_generation_wrap() {
424 let mut arena = Arena::new();
425 let (idx, mut generation) = arena.allocate(42);
426
427 for _ in 0..10 {
429 arena.deallocate(idx, generation);
430 let (_, new_generation) = arena.allocate(100);
431 generation = new_generation;
432 }
433
434 assert!(arena.is_valid(idx, generation));
436 }
437
438 #[test]
439 fn test_arena_get_mut() {
440 let mut arena = Arena::new();
441 let (idx, generation) = arena.allocate(42);
442
443 if let Some(val) = arena.get_mut(idx, generation) {
444 *val = 100;
445 }
446
447 assert_eq!(arena.get(idx, generation), Some(&100));
448 }
449
450 #[test]
451 fn test_arena_with_capacity() {
452 let mut arena = Arena::<i32>::with_capacity(100);
453 assert!(arena.is_empty());
454 assert!(arena.capacity() >= 100);
455
456 for i in 0..100 {
458 arena.allocate(i);
459 }
460 assert_eq!(arena.len(), 100);
461 }
462}