nb_tree/tree/entry/
mod.rs

1pub mod detached;
2pub mod node;
3
4use itertools::FoldWhile::{Continue, Done};
5use itertools::Itertools;
6
7//TODO: less/no replacement?
8use replace_with::{replace_with_or_abort, replace_with_or_abort_and_return};
9use std::hash::Hash;
10use std::ops::{Deref, DerefMut};
11
12use crate::path::Path;
13
14use self::detached::DetachedEntry;
15use self::node::Node;
16
17use super::iter::depth::Traversal;
18use super::{NodeIDX, Tree};
19
20pub(super) const TREEBOUND: bool = false;
21pub(super) const NODEBOUND: bool = true;
22
23pub enum Entry<R, N, B, const BOUND: bool>
24where
25    R: Deref<Target = Tree<N, B>>,
26{
27    Node(Node<R, N, B, BOUND>),
28    Detached(DetachedEntry<R, N, B, BOUND>),
29}
30
31pub type TreeRefEntry<'a, N, B, const BOUND: bool> = Entry<&'a Tree<N, B>, N, B, BOUND>;
32pub type TreeMutEntry<'a, N, B, const BOUND: bool> = Entry<&'a mut Tree<N, B>, N, B, BOUND>;
33
34impl<R, N, B, const BOUND: bool> From<Result<Node<R, N, B, BOUND>, DetachedEntry<R, N, B, BOUND>>>
35    for Entry<R, N, B, BOUND>
36where
37    R: Deref<Target = Tree<N, B>>,
38{
39    fn from(value: Result<Node<R, N, B, BOUND>, DetachedEntry<R, N, B, BOUND>>) -> Self {
40        match value {
41            Ok(n) => Entry::Node(n),
42            Err(d) => Entry::Detached(d),
43        }
44    }
45}
46
47impl<R, N, B, const BOUND: bool> From<Result<DetachedEntry<R, N, B, BOUND>, Node<R, N, B, BOUND>>>
48    for Entry<R, N, B, BOUND>
49where
50    R: Deref<Target = Tree<N, B>>,
51{
52    fn from(value: Result<DetachedEntry<R, N, B, BOUND>, Node<R, N, B, BOUND>>) -> Self {
53        match value {
54            Ok(d) => Entry::Detached(d),
55            Err(n) => Entry::Node(n),
56        }
57    }
58}
59
60impl<R, N, B, const BOUND: bool> From<Node<R, N, B, BOUND>> for Entry<R, N, B, BOUND>
61where
62    R: Deref<Target = Tree<N, B>>,
63{
64    fn from(value: Node<R, N, B, BOUND>) -> Self {
65        Entry::Node(value)
66    }
67}
68
69impl<R, N, B, const BOUND: bool> From<DetachedEntry<R, N, B, BOUND>> for Entry<R, N, B, BOUND>
70where
71    R: Deref<Target = Tree<N, B>>,
72{
73    fn from(value: DetachedEntry<R, N, B, BOUND>) -> Self {
74        Entry::Detached(value)
75    }
76}
77
78impl<R, N, B, const BOUND: bool> Entry<R, N, B, BOUND>
79where
80    R: Deref<Target = Tree<N, B>>,
81{
82    pub fn node(&self) -> Option<&Node<R, N, B, BOUND>> {
83        match self {
84            Entry::Node(node) => Some(node),
85            Entry::Detached(_) => None,
86        }
87    }
88
89    pub fn detached(&self) -> Option<&DetachedEntry<R, N, B, BOUND>> {
90        match self {
91            Entry::Node(_) => None,
92            Entry::Detached(detached) => Some(detached),
93        }
94    }
95
96    pub fn node_mut(&mut self) -> Option<&mut Node<R, N, B, BOUND>> {
97        match self {
98            Entry::Node(node) => Some(node),
99            Entry::Detached(_) => None,
100        }
101    }
102
103    pub fn detached_mut(&mut self) -> Option<&mut DetachedEntry<R, N, B, BOUND>> {
104        match self {
105            Entry::Node(_) => None,
106            Entry::Detached(detached) => Some(detached),
107        }
108    }
109
110    pub fn is_node(&self) -> bool {
111        match self {
112            Entry::Node(_) => true,
113            Entry::Detached(_) => false,
114        }
115    }
116
117    pub fn is_detached(&self) -> bool {
118        !self.is_node()
119    }
120
121    pub fn branch(&self) -> Option<&B> {
122        match self {
123            Entry::Node(attached) => attached.branch(),
124            Entry::Detached(detached) => detached.branch(),
125        }
126    }
127
128    pub fn path(&self) -> &Path<B> {
129        match self {
130            Entry::Node(attached) => attached.path(),
131            Entry::Detached(detached) => detached.path(),
132        }
133    }
134
135    pub fn value(&self) -> Option<&N> {
136        match self {
137            Entry::Node(attached) => Some(attached.value()),
138            Entry::Detached(_) => None,
139        }
140    }
141}
142
143impl<R, N, B> Entry<R, N, B, TREEBOUND>
144where
145    R: Deref<Target = Tree<N, B>>,
146    B: Eq + Hash + Clone,
147{
148    /// Applies the movement of the given traversal node, ignoring the contained data.
149    ///
150    /// No movement is made if the given node is a Start node or if the Step moves above the tree root.
151    pub fn apply_move<T>(&mut self, node: &Traversal<T, B>) -> Result<(), usize> {
152        if let Traversal::Step {
153            up,
154            branch,
155            data: _,
156        } = node
157        {
158            // Moves up without leaving and down. Blocks at root if overflowing
159            if self.path().len() < *up {
160                Err(*up - self.path().len())
161            } else {
162                assert!(self.move_up(*up).is_none());
163                self.move_down_branch(branch.clone());
164                Ok(())
165            }
166        } else {
167            Ok(())
168        }
169        /*TODO: check. Check apply_move_deref too.
170            return replace_with_or_abort_and_return(self, |s| {
171                if let Entry::Detached(detached) = s {
172                    // The Entry has to be empty to apply a root to it
173                    if detached.position.is_empty() {
174                        return (
175                            true,
176                            if detached.tree.get_root().is_some() {
177                                // The tree has a root
178                                let attached = detached.position.attach(0).unwrap_attached();
179                                Node::from(detached.tree, attached).into()
180                            } else {
181                                detached.into()
182                            },
183                        );
184                    } else {
185                        (false, detached.into())
186                    }
187                } else {
188                    (false, s)
189                }
190            });
191        */
192    }
193
194    //TODO: check
195    pub fn apply_move_deref<T, C>(&mut self, node: &Traversal<T, C>) -> bool
196    where
197        C: Deref<Target = B>,
198    {
199        if let Traversal::Step {
200            up,
201            branch,
202            data: _,
203        } = node
204        {
205            self.move_up(*up);
206            self.move_down(path![(*branch).clone()]);
207            true
208        } else {
209            replace_with_or_abort_and_return(self, |s| {
210                if let Entry::Detached(detached) = s {
211                    // The Entry has to be empty to apply a root to it
212                    if detached.position.is_empty() {
213                        (
214                            true,
215                            if detached.tree.get_root().is_some() {
216                                // The tree has a root
217                                let attached = detached.position.attach(0).unwrap_attached();
218                                Node::from(detached.tree, attached).into()
219                            } else {
220                                detached.into()
221                            },
222                        )
223                    } else {
224                        (false, detached.into())
225                    }
226                } else {
227                    (false, s)
228                }
229            })
230        }
231    }
232}
233
234impl<R, N, B, const BOUND: bool> Entry<R, N, B, BOUND>
235where
236    R: Deref<Target = Tree<N, B>>,
237    B: Eq + Hash,
238{
239    pub fn from(tree: R, root: NodeIDX, path: Path<B>) -> Self {
240        let mut detached = false;
241        let idxs = path
242            .iter()
243            .fold_while(Path::new(), |mut ph, b| {
244                ph.push_last(
245                    if let Some(c_idx) = tree.nodes[*ph.last().unwrap_or(&root)].children.get(b) {
246                        *c_idx
247                    } else {
248                        detached = true;
249                        return Done(ph);
250                    },
251                );
252                Continue(ph)
253            })
254            .into_inner();
255        if detached {
256            Self::Detached((tree, path, idxs).into())
257        } else {
258            Self::Node((tree, path, idxs).into())
259        }
260    }
261}
262
263impl<R, N, B> Entry<R, N, B, TREEBOUND>
264where
265    R: DerefMut<Target = Tree<N, B>>,
266    B: Eq + Hash + Clone,
267{
268    pub fn remove_subtree(self) -> Self {
269        match self {
270            Entry::Node(node) => node.remove_subtree().into(),
271            Entry::Detached(_) => self,
272        }
273    }
274}
275
276impl<R, N, B, const BOUND: bool> Entry<R, N, B, BOUND>
277where
278    R: DerefMut<Target = Tree<N, B>>,
279    B: Eq + Hash + Clone,
280{
281    pub fn and_modify<F>(mut self, f: F) -> Self
282    where
283        F: FnOnce(&mut N),
284    {
285        if let Entry::Node(ref mut node) = self {
286            f(node.value_mut());
287        }
288        self
289    }
290    //TODO: compare to insert
291    pub fn apply_data(&mut self, node: Traversal<N, B>) -> bool {
292        let mut r = true;
293        replace_with_or_abort(self, |s| match s {
294            Entry::Node(mut n) => {
295                n.insert(node.take());
296                n.into()
297            }
298            Entry::Detached(d) => d
299                .insert(node.take())
300                .map_err(|e| {
301                    r = false;
302                    e
303                })
304                .into(),
305        });
306        r
307    }
308}
309impl<R, N, B> Entry<R, N, B, TREEBOUND>
310where
311    R: DerefMut<Target = Tree<N, B>>,
312    B: Eq + Hash + Clone,
313{
314    pub fn apply(&mut self, node: Traversal<N, B>) -> bool {
315        self.apply_move(&node).is_ok() && self.apply_data(node)
316    }
317}
318
319impl<R, N, B> Entry<R, N, B, TREEBOUND>
320where
321    R: DerefMut<Target = Tree<N, B>>,
322    N: Clone + Default,
323    B: Eq + Hash + Clone + Default,
324{
325    pub fn apply_extend(&mut self, node: Traversal<N, B>) -> bool {
326        if let Traversal::Start(value) = node {
327            return replace_with_or_abort_and_return(self, |s| {
328                if let Entry::Detached(detached) = s {
329                    if !detached.position.is_rooted() {
330                        (true, detached.insert(value.clone()).into())
331                    } else {
332                        (false, detached.into())
333                    }
334                } else {
335                    (false, s)
336                }
337            });
338        }
339        self.move_up(node.up());
340        self.move_down(path![node.branch().unwrap().clone()]);
341        //TODO: success management
342        let r = true;
343        replace_with_or_abort(self, |s| match s {
344            Entry::Node(mut n) => {
345                n.insert(node.take());
346                n.into()
347            }
348            Entry::Detached(d) => d.insert_extend(node.take()).into(),
349        });
350
351        r
352    }
353}
354
355impl<R, N, B> Entry<R, N, B, TREEBOUND>
356where
357    R: Deref<Target = Tree<N, B>>,
358    B: Eq + Hash + Clone,
359{
360    pub fn move_down(&mut self, path: Path<B>) {
361        replace_with_or_abort(self, |s| match s {
362            Entry::Node(node) => node.move_down(path),
363            Entry::Detached(mut detached) => {
364                detached.move_down(path);
365                detached.into_entry()
366            }
367        })
368    }
369    pub fn move_down_branch(&mut self, branch: B) {
370        replace_with_or_abort(self, |s| match s {
371            Entry::Node(node) => node.move_down_branch(branch),
372            Entry::Detached(mut detached) => {
373                detached.move_down_branch(branch);
374                Entry::Detached(detached)
375            }
376        })
377    }
378    pub fn move_up(&mut self, up: usize) -> Option<usize> {
379        let mut overflow = None;
380        replace_with_or_abort(self, |s| match s {
381            Entry::Node(mut node) => {
382                overflow = node.move_up(up);
383                node.into_entry()
384            }
385            Entry::Detached(detached) => {
386                let (e, o) = detached.move_up(up);
387                overflow = o;
388                e
389            }
390        });
391        overflow
392    }
393    pub fn move_to_attached(&mut self) {
394        replace_with_or_abort(self, |s| {
395            if let Entry::Detached(detached) = s {
396                detached.move_to_attached().into()
397            } else {
398                s
399            }
400        });
401    }
402}
403
404impl<R, N, B, const BOUND: bool> Entry<R, N, B, BOUND>
405where
406    R: Deref<Target = Tree<N, B>>,
407    B: Eq + Hash + Clone,
408{
409    pub fn offshoot_len(&self) -> usize {
410        match self {
411            Entry::Node(_) => 0,
412            Entry::Detached(detached) => detached.offshoot_len(),
413        }
414    }
415}
416impl<R, N, B, const BOUND: bool> Entry<R, N, B, BOUND>
417where
418    R: DerefMut<Target = Tree<N, B>>,
419    B: Eq + Hash + Clone,
420{
421    pub fn or_insert(&mut self, value: N) -> &mut N {
422        if self.is_detached() {
423            /*self.detached()
424            .unwrap()
425            .position
426            .detached_at()
427            .unwrap_or_else(|| panic!("The entry is not rooted"));*/
428            //replace_with_or_abort(self, |mut s| s.detached_mut().unwrap().insert(value).into());
429            replace_with_or_abort(self, |s| {
430                if let Entry::Detached(detached) = s {
431                    detached.insert(value).into()
432                } else {
433                    s
434                }
435            });
436        }
437        let idx = *self.node().unwrap().position.at();
438        //(o) self.node_mut().map(|node| &mut node.tree.nodes[idx].value)
439        &mut self.node_mut().unwrap().tree.nodes[idx].value
440    }
441
442    pub fn insert(&mut self, value: N) -> Option<&mut N> {
443        replace_with_or_abort(self, |s| match s {
444            //TODO: no panic? return None?
445            Entry::Detached(detached_entry) => {
446                /*detached_entry
447                .position
448                .detached_at()
449                .unwrap_or_else(|| panic!("The entry is not rooted"));*/
450                detached_entry.insert(value).into()
451            }
452            Entry::Node(mut node) => {
453                node.insert(value);
454                node.into_entry()
455            }
456        });
457
458        let idx = *self.node().unwrap().position.at();
459        self.node_mut().map(|node| &mut node.tree.nodes[idx].value)
460    }
461}
462
463impl<R, N, B> Entry<R, N, B, TREEBOUND>
464where
465    R: DerefMut<Target = Tree<N, B>>,
466    N: Default,
467    B: Default + Eq + Hash + Clone,
468{
469    pub fn or_insert_extend(&mut self, value: N) -> &mut N {
470        replace_with_or_abort(self, |s| {
471            if let Entry::Detached(detached_entry) = s {
472                detached_entry.insert_extend(value).into()
473            } else {
474                s
475            }
476        });
477        let idx = *self.node().unwrap().position.at();
478        &mut self.node_mut().unwrap().tree.nodes[idx].value
479    }
480
481    pub fn insert_extend(&mut self, value: N) -> &mut N {
482        replace_with_or_abort(self, |s| match s {
483            Entry::Detached(detached_entry) => detached_entry.insert_extend(value).into(),
484            Entry::Node(mut node) => {
485                node.insert(value);
486                node.into()
487            }
488        });
489        let idx = *self.node().unwrap().position.at();
490        &mut self.node_mut().unwrap().tree.nodes[idx].value
491    }
492}