1use std::ops::ControlFlow;
2
3use super::{AsNodePath, InsertTransaction, Nodes, RemovedValues, TreeValues, ValueId};
4
5#[derive(Debug)]
6pub struct TreeView<'tree, T> {
7 pub offset: &'tree [u16],
8 pub values: &'tree mut TreeValues<T>,
9 pub layout: &'tree mut Nodes,
10 pub removed_values: &'tree mut RemovedValues,
11}
12
13impl<'tree, T> TreeView<'tree, T> {
14 pub fn new(
15 offset: &'tree [u16],
16 layout: &'tree mut Nodes,
17 values: &'tree mut TreeValues<T>,
18 removed_values: &'tree mut RemovedValues,
19 ) -> Self {
20 Self {
21 offset,
22 values,
23 layout,
24 removed_values,
25 }
26 }
27
28 pub fn view(&mut self) -> TreeView<'_, T> {
29 TreeView::new(self.offset, self.layout, self.values, self.removed_values)
30 }
31
32 pub fn get_mut(&mut self, value_id: ValueId) -> Option<&mut T> {
34 self.values.get_mut(value_id).map(|(_, value)| value)
35 }
36
37 pub fn get(&self, value_id: ValueId) -> Option<&T> {
39 self.values.get(value_id).map(|(_, value)| value)
40 }
41
42 pub fn contains(&self, key: ValueId) -> bool {
43 self.values.get(key).is_some()
44 }
45
46 pub fn layout_len(&self) -> usize {
48 self.layout.len()
49 }
50
51 pub fn for_each<F, U>(&mut self, mut f: F) -> Option<U>
52 where
53 F: FnMut(&[u16], &mut T, TreeView<'_, T>) -> ControlFlow<U>,
54 {
55 for index in 0..self.layout.len() {
56 let node = &mut self.layout.inner[index];
57 match self.values.with_mut(node.value, |(offset, value), values| {
58 let tree_view = TreeView::new(offset, &mut node.children, values, self.removed_values);
59 f(offset, value, tree_view)
60 }) {
61 ControlFlow::Continue(_) => continue,
62 ControlFlow::Break(value) => return Some(value),
63 }
64 }
65
66 None
67 }
68
69 fn path_ref(&self, id: impl Into<ValueId>) -> &[u16] {
77 let id = id.into();
78 let (path, _) = self
79 .values
80 .get(id)
81 .expect("an id should always be associated with a path");
82 path
83 }
84
85 pub fn path(&self, id: impl Into<ValueId>) -> Box<[u16]> {
93 self.path_ref(id).into()
94 }
95
96 fn id(&self, path: &[u16]) -> Option<ValueId> {
98 self.layout.with(path, |nodes| nodes.value())
99 }
100
101 pub fn get_node_and_value(&self, path: &[u16]) -> Option<(ValueId, &T)> {
105 let id = self.id(path)?;
106 self.values.get(id).map(|(_, val)| (id, val))
107 }
108
109 pub fn insert<'a>(&'a mut self, parent: &'a [u16]) -> InsertTransaction<'a, 'tree, T> {
122 InsertTransaction::new(self, parent)
123 }
124
125 pub fn truncate_children<F>(&mut self, f: &mut F)
127 where
128 F: FnMut(T),
129 {
130 self.layout.clear(self.values, self.removed_values, f);
131 }
132
133 pub fn relative_remove<F>(&mut self, path: &[u16], f: &mut F)
136 where
137 F: FnMut(T),
138 {
139 if self.layout.is_empty() {
140 return;
141 }
142
143 let (path, index) = path.split_parent().expect("a value will always exist within the tree");
146
147 let node = self.layout.with_mut(path, |nodes| {
148 let node = nodes.remove(index);
149
150 nodes.inner[index..].iter_mut().for_each(|node| {
151 let (path, _) = self.values.get_mut(node.value).expect("every node has a value");
153 path[path.len() - 1] -= 1;
154
155 let path = path.clone();
157 node.reparent(&path, self.values);
159 });
160
161 node
162 });
163
164 if let Some(mut node) = node {
165 let value_key = node.value();
166 _ = self
167 .values
168 .remove(value_key)
169 .expect("a node is always associated with a value");
170 self.removed_values.insert(value_key);
171 node.children.clear(self.values, self.removed_values, f);
172 }
173 }
174
175 pub fn with_value_mut<F, V>(&mut self, value_id: ValueId, f: F) -> Option<V>
182 where
183 F: FnOnce(&[u16], &mut T, TreeView<'_, T>) -> V,
184 {
185 let mut ticket = self.values.checkout(value_id);
186 let (path, value) = &mut *ticket;
187 let node = self.layout.get_by_path_mut(&path[self.offset.len()..])?;
188 let view = TreeView {
189 offset: path,
190 values: self.values,
191 layout: node.children_mut(),
192 removed_values: self.removed_values,
193 };
194 let value = f(path, value, view);
195 self.values.restore(ticket);
196 Some(value)
197 }
198
199 pub fn nodes_and_values(&self) -> (&[super::Node], &TreeValues<T>) {
200 (self.layout, self.values)
201 }
202
203 #[cfg(test)]
204 fn get_ref_by_path(&self, path: &[u16]) -> Option<&T> {
205 let relative = &path[self.offset.len()..];
206 let id = self.id(relative)?;
207 self.values.get(id).map(|(_, val)| val)
208 }
209}
210
211#[cfg(test)]
212mod test {
213 use super::*;
214 use crate::tree::{Tree, root_node};
215
216 #[test]
217 fn insert_and_commit() {
218 }
228
229 #[test]
230 fn insert_without_commit() {
231 }
237
238 #[test]
239 fn get_by_path() {
240 let mut tree = Tree::empty();
241 let mut tree = tree.view();
242 let node_id = tree.insert(root_node()).commit_child(1).unwrap();
243 let path = tree.path(node_id);
244 tree.insert(&path).commit_child(2);
245
246 let one = tree.get_ref_by_path(&[0]).unwrap();
247 let two = tree.get_ref_by_path(&[0, 0]).unwrap();
248
249 assert_eq!(*one, 1);
250 assert_eq!(*two, 2);
251 }
252
253 #[test]
254 fn with_node_id_reading_checkedout_value() {
255 let mut tree = Tree::empty();
256 let mut tree = tree.view();
257 let key = tree.insert(root_node()).commit_child(0).unwrap();
258 tree.insert(root_node()).commit_child(1);
259 tree.with_value_mut(key, |_path, _value, mut tree| {
260 assert!(tree.get_mut(key).is_none());
262 });
263 }
264
265 #[test]
266 fn remove_children() {
267 let mut tree = Tree::<u32>::empty();
268 let mut tree = tree.view();
269 tree.insert(root_node()).commit_child(1);
270 let path = &[0, 0];
271 tree.insert(path).commit_at(2);
272
273 assert!(tree.get_ref_by_path(path).is_some());
274 tree.relative_remove(path, &mut |_| {});
275 assert!(tree.get_ref_by_path(path).is_none());
276 }
277
278 #[test]
285 fn insert_at_path() {
286 let mut tree = Tree::empty();
287 let mut tree = tree.view();
288 let key = tree.insert(root_node()).commit_child(0).unwrap();
292 let _sibling_path = tree.path_ref(key);
293
294 let key_1 = tree.insert(root_node()).commit_child(1).unwrap();
296 let parent: Box<_> = tree.path_ref(key_1).into();
297
298 let key_1_0 = tree.insert(&parent).commit_child(5).unwrap();
300 let key_1_1 = tree.insert(&parent).commit_child(6).unwrap();
301
302 assert_eq!(tree.path_ref(key_1), &[1]);
305 assert_eq!(tree.path_ref(key_1_0), &[1, 0]);
306 assert_eq!(tree.path_ref(key_1_1), &[1, 1]);
307
308 let insert_at = &[0];
311 tree.insert(insert_at).commit_at(123).unwrap();
312
313 assert_eq!(tree.path_ref(key_1), &[2]);
316 assert_eq!(tree.path_ref(key_1_0), &[2, 0]);
317 assert_eq!(tree.path_ref(key_1_1), &[2, 1]);
318
319 let insert_at = [3];
322 let key_3 = tree.insert(&insert_at).commit_at(999).unwrap();
323
324 assert_eq!(tree.path_ref(key_3), &[3]);
326 }
327
328 #[test]
329 fn modify_tree() {
330 let mut tree = Tree::<usize>::empty();
331 tree.view().insert(root_node()).commit_child(123);
332 let path = &[0, 0];
333 tree.view().insert(path).commit_at(1);
334
335 let mut tree = tree.view();
336 tree.for_each(|_path, outer_value, mut children| {
337 children.for_each(|_path, inner_value, mut children| {
338 let parent = &[0, 0];
339 children.insert(parent).commit_child(999);
340 let path = &[0, 0, 0];
341 let value = children.get_ref_by_path(path).unwrap();
342 assert_eq!(*value, 999);
343 assert_eq!(*outer_value, 123);
344 assert_eq!(*inner_value, 1);
345 ControlFlow::Continue::<(), _>(())
346 });
347 ControlFlow::Break(())
348 });
349 }
350}