Skip to main content

anathema_store/tree/
transactions.rs

1use super::TreeView;
2use crate::slab::Key;
3use crate::tree::AsNodePath;
4use crate::tree::nodepath::new_node_path;
5
6pub struct InsertTransaction<'a, 'tree, T> {
7    tree: &'a mut TreeView<'tree, T>,
8    node_id: Key,
9    source: &'a [u16],
10}
11
12impl<'a, 'tree, T> InsertTransaction<'a, 'tree, T> {
13    pub fn new(tree: &'a mut TreeView<'tree, T>, source: &'a [u16]) -> Self {
14        let node_id = tree.values.next_id();
15        Self { tree, node_id, source }
16    }
17
18    pub fn node_id(&self) -> Key {
19        self.node_id
20    }
21
22    /// Insert a child under a given parent.
23    /// This will return `None` if the parent does not exist
24    pub fn commit_child(self, value: T) -> Option<Key> {
25        assert_eq!(self.tree.offset, &self.source[..self.tree.offset.len()]);
26        let relative = &self.source[self.tree.offset.len()..];
27
28        let node_id = self.tree.layout.with_mut(relative, |nodes| {
29            // The node path is the source + len of children in source
30            let node_path = new_node_path(self.source, nodes.len() as u16);
31
32            let node_id = self.tree.values.insert((node_path, value));
33            nodes.push(node_id);
34            node_id
35        })?;
36
37        debug_assert_eq!(node_id, self.node_id);
38        Some(self.node_id)
39    }
40
41    /// Insert a node at a given path.
42    /// This will force all the values **after** the new node
43    /// (along with all the children of the values) to have their paths updated.
44    pub fn commit_at(self, value: T) -> Option<Key> {
45        let (parent, index) = self.source.split_parent()?;
46
47        let node_id = self.tree.layout.with_mut(parent, |siblings| {
48            let path = crate::tree::nodepath::join(self.tree.offset, self.source);
49            let value_id = self.tree.values.insert((path, value));
50
51            // Insert value id at a given index...
52            siblings.insert(index, value_id);
53
54            // ... and update the path to the succeeding siblings
55            siblings.inner[index + 1..].iter_mut().for_each(|node| {
56                // Update the subsequent siblings by bumping their index by one
57                let (path, _) = self.tree.values.get_mut(node.value).expect("every node has a value");
58                path[path.len() - 1] += 1;
59                let path = path.clone();
60
61                // Update the root of all the children of the preceding siblings
62                node.reparent(&path, self.tree.values);
63            });
64            value_id
65        })?;
66
67        debug_assert_eq!(node_id, self.node_id);
68        Some(node_id)
69    }
70}