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}