generational_indextree/
arena.rs

1//! Arena.
2
3#[cfg(not(feature = "std"))]
4use core::ops::{Index, IndexMut};
5#[cfg(feature = "std")]
6use std::ops::{Index, IndexMut};
7
8use generational_arena::Arena as GenerationalArena;
9#[cfg(feature = "deser")]
10use serde::{Deserialize, Serialize};
11
12#[cfg(feature = "par_iter")]
13use rayon::prelude::*;
14
15use crate::{Node, NodeId};
16
17#[derive(Clone)]
18#[cfg_attr(feature = "deser", derive(Deserialize, Serialize))]
19/// An `Arena` structure containing certain [`Node`]s.
20///
21/// [`Node`]: struct.Node.html
22pub struct Arena<T> {
23    pub(crate) nodes: GenerationalArena<Node<T>>,
24}
25
26impl<T> Arena<T> {
27    /// Creates a new empty `Arena`.
28    pub fn new() -> Arena<T> {
29        Self::default()
30    }
31
32    /// Create a new empty `Arena` with pre-allocated memory for `n` items.
33    pub fn with_capacity(n: usize) -> Arena<T> {
34        Self {
35            nodes: GenerationalArena::with_capacity(n),
36        }
37    }
38
39    /// Creates a new node from its associated data.
40    ///
41    /// # Panics
42    ///
43    /// Panics if the arena already has `usize::max_value()` nodes.
44    ///
45    /// # Examples
46    ///
47    /// ```
48    /// # use generational_indextree::Arena;
49    /// let mut arena = Arena::new();
50    /// let foo = arena.new_node("foo");
51    ///
52    /// assert_eq!(*arena[foo].get(), "foo");
53    /// ```
54    pub fn new_node(&mut self, data: T) -> NodeId {
55        NodeId::from_index(self.nodes.insert(Node::new(data)))
56    }
57
58    /// Creates a new node via specified `create` function.
59    ///
60    /// `create` is called with the new node's node ID, allowing nodes that know their own ID.
61    ///
62    /// # Panics
63    ///
64    /// Panics if the arena already has `usize::max_value()` nodes.
65    ///
66    /// # Examples
67    ///
68    /// ```
69    /// # use generational_indextree::{Arena, NodeId};
70    /// let mut arena = Arena::new();
71    /// struct A { id: NodeId, val: u32 }
72    /// let foo = arena.new_node_with(|id| A { id, val: 10 });
73    ///
74    /// assert_eq!(arena[foo].get().val, 10);
75    /// assert_eq!(arena[foo].get().id, foo);
76    /// ```
77    pub fn new_node_with(&mut self, create: impl FnOnce(NodeId) -> T) -> NodeId {
78        NodeId::from_index(
79            self.nodes
80                .insert_with(|idx| Node::new(create(NodeId::from_index(idx)))),
81        )
82    }
83
84    /// Counts the number of nodes in arena and returns it.
85    ///
86    /// # Examples
87    ///
88    /// ```
89    /// # use generational_indextree::Arena;
90    /// let mut arena = Arena::new();
91    /// let foo = arena.new_node("foo");
92    /// let _bar = arena.new_node("bar");
93    /// assert_eq!(arena.count(), 2);
94    ///
95    /// foo.remove(&mut arena);
96    /// assert_eq!(arena.count(), 1);
97    /// ```
98    pub fn count(&self) -> usize {
99        self.nodes.len()
100    }
101
102    /// Returns `true` if arena has no nodes, `false` otherwise.
103    ///
104    /// # Examples
105    ///
106    /// ```
107    /// # use generational_indextree::Arena;
108    /// let mut arena = Arena::new();
109    /// assert!(arena.is_empty());
110    ///
111    /// let foo = arena.new_node("foo");
112    /// assert!(!arena.is_empty());
113    ///
114    /// foo.remove(&mut arena);
115    /// assert!(arena.is_empty());
116    /// ```
117    pub fn is_empty(&self) -> bool {
118        self.count() == 0
119    }
120
121    /// Returns a reference to the node with the given id if in the arena.
122    ///
123    /// Returns `None` if not available.
124    ///
125    /// # Examples
126    ///
127    /// ```
128    /// # use generational_indextree::{Arena, NodeId};
129    /// let mut arena = Arena::new();
130    /// let foo = arena.new_node("foo");
131    /// assert_eq!(arena.get(foo).map(|node| *node.get()), Some("foo"));
132    /// ```
133    ///
134    /// Note that this does not check whether the given node ID is created by
135    /// the arena.
136    ///
137    /// ```
138    /// # use generational_indextree::Arena;
139    /// let mut arena = Arena::new();
140    /// let foo = arena.new_node("foo");
141    /// let bar = arena.new_node("bar");
142    /// assert_eq!(arena.get(foo).map(|node| *node.get()), Some("foo"));
143    ///
144    /// let mut another_arena = Arena::new();
145    /// let _ = another_arena.new_node("Another arena");
146    /// assert_eq!(another_arena.get(foo).map(|node| *node.get()), Some("Another arena"));
147    /// assert!(another_arena.get(bar).is_none());
148    /// ```
149    pub fn get(&self, id: NodeId) -> Option<&Node<T>> {
150        self.nodes.get(id.get_index())
151    }
152
153    /// Returns a mutable reference to the node with the given id if in the
154    /// arena.
155    ///
156    /// Returns `None` if not available.
157    ///
158    /// # Examples
159    ///
160    /// ```
161    /// # use generational_indextree::{Arena, NodeId};
162    /// let mut arena = Arena::new();
163    /// let foo = arena.new_node("foo");
164    /// assert_eq!(arena.get(foo).map(|node| *node.get()), Some("foo"));
165    ///
166    /// *arena.get_mut(foo).expect("The `foo` node exists").get_mut() = "FOO!";
167    /// assert_eq!(arena.get(foo).map(|node| *node.get()), Some("FOO!"));
168    /// ```
169    pub fn get_mut(&mut self, id: NodeId) -> Option<&mut Node<T>> {
170        self.nodes.get_mut(id.get_index())
171    }
172
173    /// Get a pair of exclusive references to the elements at index `i1` and `i2` if it is in the
174    /// arena.
175    ///
176    /// If the element at index `i1` or `i2` is not in the arena, then `None` is returned for this
177    /// element.
178    ///
179    /// # Panics
180    ///
181    /// Panics if `i1` and `i2` are pointing to the same item of the arena.
182    ///
183    /// # Examples
184    ///
185    /// ```
186    /// use generational_indextree::Arena;
187    ///
188    /// let mut arena = Arena::new();
189    /// let idx1 = arena.new_node("foo");
190    /// let idx2 = arena.new_node("bar");
191    ///
192    /// {
193    ///     let (item1, item2) = arena.get2_mut(idx1, idx2);
194    ///
195    ///     *item1.unwrap().get_mut() = "jig";
196    ///     *item2.unwrap().get_mut() = "saw";
197    /// }
198    ///
199    /// assert_eq!(arena[idx1].get(), &"jig");
200    /// assert_eq!(arena[idx2].get(), &"saw");
201    /// ```
202    pub fn get2_mut(
203        &mut self,
204        i1: NodeId,
205        i2: NodeId,
206    ) -> (Option<&mut Node<T>>, Option<&mut Node<T>>) {
207        self.nodes.get2_mut(i1.get_index(), i2.get_index())
208    }
209
210    /// Returns an iterator of all nodes in the arena in storage-order.
211    ///
212    /// # Examples
213    ///
214    /// ```
215    /// # use generational_indextree::Arena;
216    /// let mut arena = Arena::new();
217    /// let _foo = arena.new_node("foo");
218    /// let _bar = arena.new_node("bar");
219    ///
220    /// let mut iter = arena.iter();
221    /// assert_eq!(iter.next().map(|node| *node.get()), Some("foo"));
222    /// assert_eq!(iter.next().map(|node| *node.get()), Some("bar"));
223    /// assert_eq!(iter.next().map(|node| *node.get()), None);
224    /// ```
225    ///
226    /// ```
227    /// # use generational_indextree::Arena;
228    /// let mut arena = Arena::new();
229    /// let _foo = arena.new_node("foo");
230    /// let bar = arena.new_node("bar");
231    /// bar.remove(&mut arena);
232    ///
233    /// let mut iter = arena.iter();
234    /// assert_eq!(iter.next().map(|node| *node.get()), Some("foo"));
235    /// assert_eq!(iter.next().map(|node| *node.get()), None);
236    /// ```
237    pub fn iter(&self) -> impl Iterator<Item = &Node<T>> {
238        self.nodes.iter().map(|pair| pair.1)
239    }
240
241    /// Returns an iterator of all pairs (NodeId, &Node<T>) in the arena in storage-order.
242    ///
243    /// ```
244    /// # use generational_indextree::Arena;
245    /// let mut arena = Arena::new();
246    /// let _foo = arena.new_node("foo");
247    /// let _bar = arena.new_node("bar");
248    ///
249    /// let mut iter = arena.iter_pairs();
250    /// assert_eq!(iter.next().map(|node| (node.0, *node.1.get())), Some((_foo, "foo")));
251    /// assert_eq!(iter.next().map(|node| (node.0, *node.1.get())), Some((_bar, "bar")));
252    /// assert_eq!(iter.next().map(|node| (node.0, *node.1.get())), None);
253    /// ```
254    pub fn iter_pairs(&self) -> impl Iterator<Item = (NodeId, &Node<T>)> {
255        self.nodes
256            .iter()
257            .map(|pair| (NodeId::from_index(pair.0), pair.1))
258    }
259}
260
261impl<T> Default for Arena<T> {
262    fn default() -> Self {
263        Self {
264            nodes: GenerationalArena::new(),
265        }
266    }
267}
268
269impl<T: core::fmt::Debug> core::fmt::Debug for Arena<T> {
270    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
271        f.debug_list()
272            .entries(self.nodes.iter().map(|(idx, node)| (idx, &node.data)))
273            .finish()
274    }
275}
276
277impl<T> Index<NodeId> for Arena<T> {
278    type Output = Node<T>;
279
280    fn index(&self, node: NodeId) -> &Node<T> {
281        &self.nodes[node.get_index()]
282    }
283}
284
285impl<T> IndexMut<NodeId> for Arena<T> {
286    fn index_mut(&mut self, node: NodeId) -> &mut Node<T> {
287        &mut self.nodes[node.get_index()]
288    }
289}
290
291impl<T: PartialEq> PartialEq for Arena<T> {
292    fn eq(&self, other: &Self) -> bool {
293        let mut equal = self.nodes.len() == other.nodes.len();
294        let mut self_iter = self.iter();
295        let mut other_iter = other.iter();
296        while equal {
297            let lhs = self_iter.next();
298            let rhs = other_iter.next();
299            equal = lhs == rhs;
300            if lhs.is_none() {
301                break;
302            }
303        }
304        equal
305    }
306}
307
308impl<T: PartialEq> Eq for Arena<T> {}
309
310#[test]
311fn reuse_node() {
312    let mut arena = Arena::with_capacity(3);
313    let n1_id = arena.new_node("1");
314    let n2_id = arena.new_node("2");
315    let n3_id = arena.new_node("3");
316    n1_id.remove(&mut arena);
317    n2_id.remove(&mut arena);
318    n3_id.remove(&mut arena);
319    let new_n1_id = arena.new_node("1");
320    let new_n2_id = arena.new_node("2");
321    let new_n3_id = arena.new_node("3");
322    assert_eq!(arena.nodes.len(), 3);
323    assert_ne!(n1_id, new_n1_id);
324    assert_ne!(n2_id, new_n2_id);
325    assert_ne!(n3_id, new_n3_id);
326}
327
328#[cfg(feature = "std")]
329#[test]
330fn debug_arena() {
331    let mut arena = Arena::with_capacity(10);
332    let _n1_id = arena.new_node("1");
333    let n2_id = arena.new_node("2");
334    let n3_id = arena.new_node("3");
335    let n4_id = arena.new_node("4");
336    let _n5_id = arena.new_node("5");
337    n2_id.remove(&mut arena);
338    n3_id.remove(&mut arena);
339    n4_id.remove(&mut arena);
340    let _n6_id = arena.new_node("6");
341
342    assert_eq!(
343        format!("{:?}", arena),
344        "[(Index { index: 0, generation: 0 }, \"1\"), (Index { index: 3, generation: 3 }, \"6\"), (Index { index: 4, generation: 0 }, \"5\")]"
345    );
346}