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#![deprecated(
20    since = "1.2.0",
21    note = "This crate is now deprecated in favor of [slab](https://crates.io/crates/slab)."
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}