Skip to main content

anathema_store/tree/
mod.rs

1use std::ops::{Deref, DerefMut};
2
3pub use self::nodepath::{AsNodePath, new_node_path, root_node};
4pub use self::transactions::InsertTransaction;
5pub use self::view::TreeView;
6use crate::slab::GenSlab;
7pub use crate::slab::Key as ValueId;
8
9mod nodepath;
10mod transactions;
11mod view;
12
13pub type TreeValues<T> = GenSlab<(Box<[u16]>, T)>;
14
15#[derive(Debug)]
16pub struct RemovedValues {
17    inner: Vec<ValueId>,
18}
19
20impl RemovedValues {
21    pub const fn new() -> Self {
22        Self { inner: vec![] }
23    }
24
25    pub fn drain(&mut self) -> impl DoubleEndedIterator<Item = ValueId> + '_ {
26        self.inner.drain(..)
27    }
28
29    pub fn insert(&mut self, value_id: ValueId) {
30        self.inner.push(value_id);
31    }
32}
33
34/// A tree where all values (`T`) are stored in a single contiguous list,
35/// and the inner tree (`Nodes`) is made up of branches with indices into
36/// the flat list.
37///
38/// This means fewer allocations when removing entire branches as we can reuse
39/// the memory for the values.
40#[derive(Debug)]
41pub struct Tree<T> {
42    layout: Nodes,
43    values: TreeValues<T>,
44    removed_values: RemovedValues,
45}
46
47impl<T> Tree<T> {
48    /// Create an empty tree
49    pub const fn empty() -> Self {
50        Self {
51            layout: Nodes::empty(),
52            values: TreeValues::empty(),
53            removed_values: RemovedValues::new(),
54        }
55    }
56
57    pub fn view(&mut self) -> TreeView<'_, T> {
58        TreeView::new(
59            root_node(),
60            &mut self.layout,
61            &mut self.values,
62            &mut self.removed_values,
63        )
64    }
65
66    /// Get a refernence to a value
67    pub fn get_ref(&mut self, value_id: ValueId) -> Option<&T> {
68        self.values.get(value_id).map(|(_, value)| value)
69    }
70
71    /// Get a mutable refernence to a value
72    pub fn get_mut(&mut self, value_id: ValueId) -> Option<&mut T> {
73        self.values.get_mut(value_id).map(|(_, value)| value)
74    }
75
76    /// Consume the tree and return the values
77    pub fn values(self) -> TreeValues<T> {
78        self.values
79    }
80
81    /// Drain the removed value ids.
82    /// This will not return keys that have been replaced.
83    pub fn drain_removed(&mut self) -> impl DoubleEndedIterator<Item = ValueId> + '_ {
84        self.removed_values.drain()
85    }
86
87    /// Perform a given operation (`F`) on a mutable reference to a value in the tree
88    /// while still having mutable access to the rest of the tree.
89    ///
90    /// # Panics
91    ///
92    /// This will panic if the value is already checked out
93    pub fn with_value_mut<F, V>(&mut self, value_id: ValueId, f: F) -> V
94    where
95        F: FnOnce(&[u16], &mut T, &mut Self) -> V,
96    {
97        let mut ticket = self.values.checkout(value_id);
98        let value = f(&ticket.value.0, &mut ticket.value.1, self);
99        self.values.restore(ticket);
100        value
101    }
102}
103
104#[derive(Debug)]
105pub struct Nodes {
106    pub(crate) inner: Vec<Node>,
107}
108
109impl Nodes {
110    pub const fn empty() -> Self {
111        Self { inner: vec![] }
112    }
113
114    /// Find a mutable node by its path
115    fn get_by_path_mut(&mut self, mut path: &[u16]) -> Option<&mut Node> {
116        let mut nodes = self;
117        loop {
118            match path {
119                [] => break None,
120                [i] if (*i as usize) < nodes.len() => break Some(&mut nodes.inner[*i as usize]),
121                // The index is outside of the node length
122                [_] => break None,
123                [i, sub_path @ ..] => {
124                    let index = *i as usize;
125                    if index >= nodes.len() {
126                        break None;
127                    }
128                    path = sub_path;
129                    nodes = &mut nodes.inner[index].children;
130                }
131            }
132        }
133    }
134
135    fn insert(&mut self, index: usize, key: ValueId) {
136        self.inner.insert(index, Node::new(key));
137    }
138
139    fn push(&mut self, key: ValueId) {
140        self.inner.push(Node::new(key));
141    }
142
143    // Clear nodes and remove associated values
144    fn clear<T, F>(&mut self, values: &mut GenSlab<(Box<[u16]>, T)>, removed_values: &mut RemovedValues, f: &mut F)
145    where
146        F: FnMut(T),
147    {
148        for mut node in self.inner.drain(..) {
149            if let Some((_path, value)) = values.remove(node.value) {
150                f(value);
151                removed_values.insert(node.value);
152            }
153            node.children.clear(values, removed_values, f);
154        }
155    }
156
157    // Unlike the clear function the remove function
158    // only remove the node, whereas the values
159    // are managed by the three.
160    fn remove(&mut self, index: usize) -> Node {
161        self.inner.remove(index)
162    }
163
164    fn with<'a, F, U: 'a>(&'a self, parent: &[u16], f: F) -> Option<U>
165    where
166        F: FnOnce(&'a Node) -> U,
167    {
168        let mut path = parent;
169        let mut nodes = self;
170        loop {
171            match path {
172                [] => break None,
173                [i] if (*i as usize) < nodes.len() => break Some(f(&nodes.inner[*i as usize])),
174                [_] => break None,
175                [i, p @ ..] => {
176                    let index = *i as usize;
177                    if index >= nodes.len() {
178                        break None;
179                    }
180                    path = p;
181                    nodes = &nodes.inner[index].children;
182                }
183            }
184        }
185    }
186
187    fn with_mut<'a, F, U: 'a>(&'a mut self, parent: &[u16], f: F) -> Option<U>
188    where
189        F: FnOnce(&'a mut Nodes) -> U,
190    {
191        let mut path = parent;
192        let mut nodes = self;
193        loop {
194            match path {
195                [] => break Some(f(nodes)),
196                [i] if (*i as usize) < nodes.len() => break Some(f(&mut nodes.inner[*i as usize].children)),
197                // The index is outside of the node length
198                [_] => break None,
199                [i, sub_path @ ..] => {
200                    let index = *i as usize;
201                    if index >= nodes.len() {
202                        break None;
203                    }
204                    path = sub_path;
205                    nodes = &mut nodes.inner[index].children;
206                }
207            }
208        }
209    }
210}
211
212impl Deref for Nodes {
213    type Target = [Node];
214
215    fn deref(&self) -> &Self::Target {
216        &self.inner
217    }
218}
219
220impl DerefMut for Nodes {
221    fn deref_mut(&mut self) -> &mut Self::Target {
222        &mut self.inner
223    }
224}
225
226#[derive(Debug)]
227pub struct Node {
228    pub(crate) value: ValueId,
229    pub(crate) children: Nodes,
230}
231
232impl Node {
233    pub fn new(val: ValueId) -> Self {
234        Self {
235            value: val,
236            children: Nodes::empty(),
237        }
238    }
239
240    pub fn value(&self) -> ValueId {
241        self.value
242    }
243
244    pub fn children(&self) -> &Nodes {
245        &self.children
246    }
247
248    fn children_mut(&mut self) -> &mut Nodes {
249        &mut self.children
250    }
251
252    fn reparent<T>(&mut self, dest: &[u16], values: &mut TreeValues<T>) {
253        let (path, _) = values.get_mut(self.value).unwrap();
254        path.reparent(dest);
255        for child in &mut self.children.inner {
256            child.reparent(dest, values);
257        }
258    }
259}