vec_arena/lib.rs
1//! A simple object arena.
2//!
3//! `Arena<T>` is basically just a `Vec<Option<T>>`, which allows you to:
4//!
5//! * Insert an object (reuse an existing [`None`] element, or append to the end).
6//! * Remove object at a specified index.
7//! * Access object at a specified index.
8//!
9//! # Examples
10//!
11//! Some data structures built using `Arena<T>`:
12//!
13//! * [Doubly linked list](https://github.com/smol-rs/vec-arena/blob/master/examples/linked-list.rs)
14//! * [Splay tree](https://github.com/smol-rs/vec-arena/blob/master/examples/splay-tree.rs)
15
16#![no_std]
17#![forbid(unsafe_code)]
18#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms)]
19#."
22)]
23
24extern crate alloc;
25
26use alloc::fmt;
27use alloc::vec;
28use alloc::vec::Vec;
29use core::iter;
30use core::mem;
31use core::ops::{Index, IndexMut};
32use core::slice;
33
34/// A slot, which is either vacant or occupied.
35///
36/// Vacant slots in arena are linked together into a singly linked list. This allows the arena to
37/// efficiently find a vacant slot before inserting a new object, or reclaiming a slot after
38/// removing an object.
39#[derive(Clone)]
40enum Slot<T> {
41 /// Vacant slot, containing index to the next slot in the linked list.
42 Vacant(usize),
43
44 /// Occupied slot, containing a value.
45 Occupied(T),
46}
47
48impl<T> Slot<T> {
49 /// Returns `true` if the slot is vacant.
50 fn is_occupied(&self) -> bool {
51 match self {
52 Slot::Vacant(_) => false,
53 Slot::Occupied(_) => true,
54 }
55 }
56}
57
58/// An object arena.
59///
60/// `Arena<T>` holds an array of slots for storing objects.
61/// Every slot is always in one of two states: occupied or vacant.
62///
63/// Essentially, this is equivalent to `Vec<Option<T>>`.
64///
65/// # Insert and remove
66///
67/// When inserting a new object into arena, a vacant slot is found and then the object is placed
68/// into the slot. If there are no vacant slots, the array is reallocated with bigger capacity.
69/// The cost of insertion is amortized `O(1)`.
70///
71/// When removing an object, the slot containing it is marked as vacant and the object is returned.
72/// The cost of removal is `O(1)`.
73///
74/// ```
75/// use vec_arena::Arena;
76///
77/// let mut arena = Arena::new();
78/// let a = arena.insert(10);
79/// let b = arena.insert(20);
80///
81/// assert_eq!(a, 0); // 10 was placed at index 0
82/// assert_eq!(b, 1); // 20 was placed at index 1
83///
84/// assert_eq!(arena.remove(a), Some(10));
85/// assert_eq!(arena.get(a), None); // slot at index 0 is now vacant
86///
87/// assert_eq!(arena.insert(30), 0); // slot at index 0 is reused
88/// ```
89///
90/// # Indexing
91///
92/// You can also access objects in an arena by index, just like you would in a [`Vec`].
93/// However, accessing a vacant slot by index or using an out-of-bounds index will result in panic.
94///
95/// ```
96/// use vec_arena::Arena;
97///
98/// let mut arena = Arena::new();
99/// let a = arena.insert(10);
100/// let b = arena.insert(20);
101///
102/// assert_eq!(arena[a], 10);
103/// assert_eq!(arena[b], 20);
104///
105/// arena[a] += arena[b];
106/// assert_eq!(arena[a], 30);
107/// ```
108///
109/// To access slots without fear of panicking, use [`get()`][`Arena::get()`] and
110/// [`get_mut()`][`Arena::get_mut()`], which return [`Option`]s.
111pub struct Arena<T> {
112 /// Slots in which objects are stored.
113 slots: Vec<Slot<T>>,
114
115 /// Number of occupied slots in the arena.
116 len: usize,
117
118 /// Index of the first vacant slot in the linked list.
119 head: usize,
120}
121
122impl<T> Arena<T> {
123 /// Constructs a new, empty arena.
124 ///
125 /// The arena will not allocate until objects are inserted into it.
126 ///
127 /// # Examples
128 ///
129 /// ```
130 /// use vec_arena::Arena;
131 ///
132 /// let mut arena: Arena<i32> = Arena::new();
133 /// ```
134 #[inline]
135 pub fn new() -> Self {
136 Arena {
137 slots: Vec::new(),
138 len: 0,
139 head: !0,
140 }
141 }
142
143 /// Constructs a new, empty arena with the specified capacity (number of slots).
144 ///
145 /// The arena will be able to hold exactly `cap` objects without reallocating.
146 /// If `cap` is 0, the arena will not allocate.
147 ///
148 /// # Examples
149 ///
150 /// ```
151 /// use vec_arena::Arena;
152 ///
153 /// let mut arena = Arena::with_capacity(10);
154 ///
155 /// assert_eq!(arena.len(), 0);
156 /// assert_eq!(arena.capacity(), 10);
157 ///
158 /// // These inserts are done without reallocating...
159 /// for i in 0..10 {
160 /// arena.insert(i);
161 /// }
162 /// assert_eq!(arena.capacity(), 10);
163 ///
164 /// // ... but this one will reallocate.
165 /// arena.insert(11);
166 /// assert!(arena.capacity() > 10);
167 /// ```
168 #[inline]
169 pub fn with_capacity(cap: usize) -> Self {
170 Arena {
171 slots: Vec::with_capacity(cap),
172 len: 0,
173 head: !0,
174 }
175 }
176
177 /// Returns the number of slots in the arena.
178 ///
179 /// # Examples
180 ///
181 /// ```
182 /// use vec_arena::Arena;
183 ///
184 /// let arena: Arena<i32> = Arena::with_capacity(10);
185 /// assert_eq!(arena.capacity(), 10);
186 /// ```
187 #[inline]
188 pub fn capacity(&self) -> usize {
189 self.slots.capacity()
190 }
191
192 /// Returns the number of occupied slots in the arena.
193 ///
194 /// # Examples
195 ///
196 /// ```
197 /// use vec_arena::Arena;
198 ///
199 /// let mut arena = Arena::new();
200 /// assert_eq!(arena.len(), 0);
201 ///
202 /// for i in 0..10 {
203 /// arena.insert(());
204 /// assert_eq!(arena.len(), i + 1);
205 /// }
206 /// ```
207 #[inline]
208 pub fn len(&self) -> usize {
209 self.len
210 }
211
212 /// Returns `true` if all slots are vacant.
213 ///
214 /// # Examples
215 ///
216 /// ```
217 /// use vec_arena::Arena;
218 ///
219 /// let mut arena = Arena::new();
220 /// assert!(arena.is_empty());
221 ///
222 /// arena.insert(1);
223 /// assert!(!arena.is_empty());
224 /// ```
225 #[inline]
226 pub fn is_empty(&self) -> bool {
227 self.len == 0
228 }
229
230 /// Returns the index of the slot that next [`insert`][`Arena::insert()`] will use if no
231 /// mutating calls take place in between.
232 ///
233 /// # Examples
234 ///
235 /// ```
236 /// use vec_arena::Arena;
237 ///
238 /// let mut arena = Arena::new();
239 ///
240 /// let a = arena.next_vacant();
241 /// let b = arena.insert(1);
242 /// assert_eq!(a, b);
243 /// let c = arena.next_vacant();
244 /// let d = arena.insert(2);
245 /// assert_eq!(c, d);
246 /// ```
247 #[inline]
248 pub fn next_vacant(&self) -> usize {
249 if self.head == !0 {
250 self.len
251 } else {
252 self.head
253 }
254 }
255
256 /// Inserts an object into the arena and returns the slot index it was stored in.
257 ///
258 /// The arena will reallocate if it's full.
259 ///
260 /// # Examples
261 ///
262 /// ```
263 /// use vec_arena::Arena;
264 ///
265 /// let mut arena = Arena::new();
266 ///
267 /// let a = arena.insert(1);
268 /// let b = arena.insert(2);
269 /// assert!(a != b);
270 /// ```
271 #[inline]
272 pub fn insert(&mut self, object: T) -> usize {
273 self.len += 1;
274
275 if self.head == !0 {
276 self.slots.push(Slot::Occupied(object));
277 self.len - 1
278 } else {
279 let index = self.head;
280 match self.slots[index] {
281 Slot::Vacant(next) => {
282 self.head = next;
283 self.slots[index] = Slot::Occupied(object);
284 }
285 Slot::Occupied(_) => unreachable!(),
286 }
287 index
288 }
289 }
290
291 /// Removes the object stored at `index` from the arena and returns it.
292 ///
293 /// If the slot is vacant or `index` is out of bounds, [`None`] will be returned.
294 ///
295 /// # Examples
296 ///
297 /// ```
298 /// use vec_arena::Arena;
299 ///
300 /// let mut arena = Arena::new();
301 /// let a = arena.insert("hello");
302 ///
303 /// assert_eq!(arena.len(), 1);
304 /// assert_eq!(arena.remove(a), Some("hello"));
305 ///
306 /// assert_eq!(arena.len(), 0);
307 /// assert_eq!(arena.remove(a), None);
308 /// ```
309 #[inline]
310 pub fn remove(&mut self, index: usize) -> Option<T> {
311 match self.slots.get_mut(index) {
312 None => None,
313 Some(&mut Slot::Vacant(_)) => None,
314 Some(slot @ &mut Slot::Occupied(_)) => {
315 if let Slot::Occupied(object) = mem::replace(slot, Slot::Vacant(self.head)) {
316 self.head = index;
317 self.len -= 1;
318 Some(object)
319 } else {
320 unreachable!();
321 }
322 }
323 }
324 }
325
326 /// Retains objects for which the closure returns `true`.
327 ///
328 /// All other objects will be removed from the arena.
329 ///
330 /// # Examples
331 ///
332 /// ```
333 /// use vec_arena::Arena;
334 ///
335 /// let mut arena = Arena::new();
336 ///
337 /// let a = arena.insert(0);
338 /// let b = arena.insert(1);
339 /// let c = arena.insert(2);
340 ///
341 /// arena.retain(|k, v| k == a || *v == 1);
342 ///
343 /// assert!(arena.get(a).is_some());
344 /// assert!(arena.get(b).is_some());
345 /// assert!(arena.get(c).is_none());
346 /// ```
347 pub fn retain<F>(&mut self, mut f: F)
348 where
349 F: FnMut(usize, &mut T) -> bool,
350 {
351 for i in 0..self.slots.len() {
352 if let Slot::Occupied(v) = &mut self.slots[i] {
353 if !f(i, v) {
354 self.remove(i);
355 }
356 }
357 }
358 }
359
360 /// Clears the arena, removing and dropping all objects it holds.
361 ///
362 /// Keeps the allocated memory for reuse.
363 ///
364 /// # Examples
365 ///
366 /// ```
367 /// use vec_arena::Arena;
368 ///
369 /// let mut arena = Arena::new();
370 /// for i in 0..10 {
371 /// arena.insert(i);
372 /// }
373 ///
374 /// assert_eq!(arena.len(), 10);
375 /// arena.clear();
376 /// assert_eq!(arena.len(), 0);
377 /// ```
378 #[inline]
379 pub fn clear(&mut self) {
380 self.slots.clear();
381 self.len = 0;
382 self.head = !0;
383 }
384
385 /// Returns a reference to the object stored at `index`.
386 ///
387 /// If the slot is vacant or `index` is out of bounds, [`None`] will be returned.
388 ///
389 /// # Examples
390 ///
391 /// ```
392 /// use vec_arena::Arena;
393 ///
394 /// let mut arena = Arena::new();
395 /// let index = arena.insert("hello");
396 ///
397 /// assert_eq!(arena.get(index), Some(&"hello"));
398 /// arena.remove(index);
399 /// assert_eq!(arena.get(index), None);
400 /// ```
401 #[inline]
402 pub fn get(&self, index: usize) -> Option<&T> {
403 match self.slots.get(index) {
404 None => None,
405 Some(&Slot::Vacant(_)) => None,
406 Some(&Slot::Occupied(ref object)) => Some(object),
407 }
408 }
409
410 /// Returns a mutable reference to the object stored at `index`.
411 ///
412 /// If the slot is vacant or `index` is out of bounds, [`None`] will be returned.
413 ///
414 /// # Examples
415 ///
416 /// ```
417 /// use vec_arena::Arena;
418 ///
419 /// let mut arena = Arena::new();
420 /// let index = arena.insert(7);
421 ///
422 /// assert_eq!(arena.get_mut(index), Some(&mut 7));
423 /// *arena.get_mut(index).unwrap() *= 10;
424 /// assert_eq!(arena.get_mut(index), Some(&mut 70));
425 /// ```
426 #[inline]
427 pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
428 match self.slots.get_mut(index) {
429 None => None,
430 Some(&mut Slot::Vacant(_)) => None,
431 Some(&mut Slot::Occupied(ref mut object)) => Some(object),
432 }
433 }
434
435 /// Swaps two objects in the arena.
436 ///
437 /// The two indices are `a` and `b`.
438 ///
439 /// # Panics
440 ///
441 /// Panics if any of the indices is out of bounds or any of the slots is vacant.
442 ///
443 /// # Examples
444 ///
445 /// ```
446 /// use vec_arena::Arena;
447 ///
448 /// let mut arena = Arena::new();
449 /// let a = arena.insert(7);
450 /// let b = arena.insert(8);
451 ///
452 /// arena.swap(a, b);
453 /// assert_eq!(arena.get(a), Some(&8));
454 /// assert_eq!(arena.get(b), Some(&7));
455 /// ```
456 #[inline]
457 pub fn swap(&mut self, a: usize, b: usize) {
458 assert!(self.slots[a].is_occupied(), "invalid object ID");
459 assert!(self.slots[b].is_occupied(), "invalid object ID");
460
461 if a != b {
462 let (a, b) = (a.min(b), a.max(b));
463 let (l, r) = self.slots.split_at_mut(b);
464 mem::swap(&mut l[a], &mut r[0]);
465 }
466 }
467
468 /// Reserves capacity for at least `additional` more objects to be inserted.
469 ///
470 /// The arena may reserve more space to avoid frequent reallocations.
471 ///
472 /// # Panics
473 ///
474 /// Panics if the new capacity overflows `usize`.
475 ///
476 /// # Examples
477 ///
478 /// ```
479 /// use vec_arena::Arena;
480 ///
481 /// let mut arena = Arena::new();
482 /// arena.insert("hello");
483 ///
484 /// arena.reserve(10);
485 /// assert!(arena.capacity() >= 11);
486 /// ```
487 pub fn reserve(&mut self, additional: usize) {
488 let vacant = self.slots.len() - self.len;
489 if additional > vacant {
490 self.slots.reserve(additional - vacant);
491 }
492 }
493
494 /// Reserves the minimum capacity for exactly `additional` more objects to be inserted.
495 ///
496 /// Note that the allocator may give the arena more space than it requests.
497 ///
498 /// # Panics
499 ///
500 /// Panics if the new capacity overflows `usize`.
501 ///
502 /// # Examples
503 ///
504 /// ```
505 /// use vec_arena::Arena;
506 ///
507 /// let mut arena = Arena::new();
508 /// arena.insert("hello");
509 ///
510 /// arena.reserve_exact(10);
511 /// assert!(arena.capacity() >= 11);
512 /// ```
513 pub fn reserve_exact(&mut self, additional: usize) {
514 let vacant = self.slots.len() - self.len;
515 if additional > vacant {
516 self.slots.reserve_exact(additional - vacant);
517 }
518 }
519
520 /// Returns an iterator over occupied slots.
521 ///
522 /// # Examples
523 ///
524 /// ```
525 /// use vec_arena::Arena;
526 ///
527 /// let mut arena = Arena::new();
528 /// arena.insert(1);
529 /// arena.insert(2);
530 /// arena.insert(4);
531 ///
532 /// let mut iterator = arena.iter();
533 /// assert_eq!(iterator.next(), Some((0, &1)));
534 /// assert_eq!(iterator.next(), Some((1, &2)));
535 /// assert_eq!(iterator.next(), Some((2, &4)));
536 /// ```
537 #[inline]
538 pub fn iter(&self) -> Iter<'_, T> {
539 Iter {
540 slots: self.slots.iter().enumerate(),
541 }
542 }
543
544 /// Returns an iterator that returns mutable references to objects.
545 ///
546 /// # Examples
547 ///
548 /// ```
549 /// use vec_arena::Arena;
550 ///
551 /// let mut arena = Arena::new();
552 /// arena.insert("zero".to_string());
553 /// arena.insert("one".to_string());
554 /// arena.insert("two".to_string());
555 ///
556 /// for (index, object) in arena.iter_mut() {
557 /// *object = index.to_string() + " " + object;
558 /// }
559 ///
560 /// let mut iterator = arena.iter();
561 /// assert_eq!(iterator.next(), Some((0, &"0 zero".to_string())));
562 /// assert_eq!(iterator.next(), Some((1, &"1 one".to_string())));
563 /// assert_eq!(iterator.next(), Some((2, &"2 two".to_string())));
564 /// ```
565 #[inline]
566 pub fn iter_mut(&mut self) -> IterMut<'_, T> {
567 IterMut {
568 slots: self.slots.iter_mut().enumerate(),
569 }
570 }
571
572 /// Shrinks the capacity of the arena as much as possible.
573 ///
574 /// It will drop down as close as possible to the length but the allocator may still inform
575 /// the arena that there is space for a few more elements.
576 ///
577 /// # Examples
578 ///
579 /// ```
580 /// use vec_arena::Arena;
581 ///
582 /// let mut arena = Arena::with_capacity(10);
583 /// arena.insert("first".to_string());
584 /// arena.insert("second".to_string());
585 /// arena.insert("third".to_string());
586 /// assert_eq!(arena.capacity(), 10);
587 /// arena.shrink_to_fit();
588 /// assert!(arena.capacity() >= 3);
589 /// ```
590 pub fn shrink_to_fit(&mut self) {
591 self.slots.shrink_to_fit();
592 }
593}
594
595impl<T> fmt::Debug for Arena<T> {
596 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
597 write!(f, "Arena {{ ... }}")
598 }
599}
600
601impl<T> Index<usize> for Arena<T> {
602 type Output = T;
603
604 #[inline]
605 fn index(&self, index: usize) -> &T {
606 self.get(index).expect("vacant slot at `index`")
607 }
608}
609
610impl<T> IndexMut<usize> for Arena<T> {
611 #[inline]
612 fn index_mut(&mut self, index: usize) -> &mut T {
613 self.get_mut(index).expect("vacant slot at `index`")
614 }
615}
616
617impl<T> Default for Arena<T> {
618 fn default() -> Self {
619 Arena::new()
620 }
621}
622
623impl<T: Clone> Clone for Arena<T> {
624 fn clone(&self) -> Self {
625 Arena {
626 slots: self.slots.clone(),
627 len: self.len,
628 head: self.head,
629 }
630 }
631}
632
633/// An iterator over the occupied slots in an [`Arena`].
634pub struct IntoIter<T> {
635 slots: iter::Enumerate<vec::IntoIter<Slot<T>>>,
636}
637
638impl<T> Iterator for IntoIter<T> {
639 type Item = (usize, T);
640
641 #[inline]
642 fn next(&mut self) -> Option<Self::Item> {
643 while let Some((index, slot)) = self.slots.next() {
644 if let Slot::Occupied(object) = slot {
645 return Some((index, object));
646 }
647 }
648 None
649 }
650}
651
652impl<T> IntoIterator for Arena<T> {
653 type Item = (usize, T);
654 type IntoIter = IntoIter<T>;
655
656 #[inline]
657 fn into_iter(self) -> Self::IntoIter {
658 IntoIter {
659 slots: self.slots.into_iter().enumerate(),
660 }
661 }
662}
663
664impl<T> iter::FromIterator<T> for Arena<T> {
665 fn from_iter<U: IntoIterator<Item = T>>(iter: U) -> Arena<T> {
666 let iter = iter.into_iter();
667 let mut arena = Arena::with_capacity(iter.size_hint().0);
668 for i in iter {
669 arena.insert(i);
670 }
671 arena
672 }
673}
674
675impl<T> fmt::Debug for IntoIter<T> {
676 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
677 write!(f, "IntoIter {{ ... }}")
678 }
679}
680
681/// An iterator over references to the occupied slots in an [`Arena`].
682pub struct Iter<'a, T> {
683 slots: iter::Enumerate<slice::Iter<'a, Slot<T>>>,
684}
685
686impl<'a, T> Iterator for Iter<'a, T> {
687 type Item = (usize, &'a T);
688
689 #[inline]
690 fn next(&mut self) -> Option<Self::Item> {
691 while let Some((index, slot)) = self.slots.next() {
692 if let Slot::Occupied(ref object) = *slot {
693 return Some((index, object));
694 }
695 }
696 None
697 }
698}
699
700impl<'a, T> IntoIterator for &'a Arena<T> {
701 type Item = (usize, &'a T);
702 type IntoIter = Iter<'a, T>;
703
704 #[inline]
705 fn into_iter(self) -> Self::IntoIter {
706 self.iter()
707 }
708}
709
710impl<'a, T> fmt::Debug for Iter<'a, T> {
711 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
712 write!(f, "Iter {{ ... }}")
713 }
714}
715
716/// An iterator over mutable references to the occupied slots in a `Arena`.
717pub struct IterMut<'a, T> {
718 slots: iter::Enumerate<slice::IterMut<'a, Slot<T>>>,
719}
720
721impl<'a, T> Iterator for IterMut<'a, T> {
722 type Item = (usize, &'a mut T);
723
724 #[inline]
725 fn next(&mut self) -> Option<Self::Item> {
726 while let Some((index, slot)) = self.slots.next() {
727 if let Slot::Occupied(ref mut object) = *slot {
728 return Some((index, object));
729 }
730 }
731 None
732 }
733}
734
735impl<'a, T> IntoIterator for &'a mut Arena<T> {
736 type Item = (usize, &'a mut T);
737 type IntoIter = IterMut<'a, T>;
738
739 #[inline]
740 fn into_iter(self) -> Self::IntoIter {
741 self.iter_mut()
742 }
743}
744
745impl<'a, T> fmt::Debug for IterMut<'a, T> {
746 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
747 write!(f, "IterMut {{ ... }}")
748 }
749}