trailtree/implement/path.rs
1use crate::{TrailTree, Cell};
2
3impl<K,T> TrailTree<K,T>
4where K: Clone + Ord
5{
6 /// Returns the previous sequential node in the layer.
7 ///
8 /// # Examples
9 ///
10 /// ```
11 /// use trailtree::TrailTree;
12 ///
13 /// let mut con = TrailTree::<u32,()>::new();
14 ///
15 /// let a = con.insert(&[5, 10]);
16 /// let b = con.insert(&[5, 20]);
17 ///
18 /// assert_eq!(con.prev(b), Some(a));
19 /// assert_eq!(con.prev(a), None);
20 /// ```
21 ///
22 /// See also [`TrailTree::next`].
23 pub fn prev(&self, id:usize) -> Option<usize>
24 {
25 self.traverse(id, false)
26 }
27
28 /// Returns the next sequential node in the layer.
29 ///
30 /// # Examples
31 ///
32 /// ```
33 /// use trailtree::TrailTree;
34 ///
35 /// let mut con = TrailTree::<u32,()>::new();
36 ///
37 /// let a = con.insert(&[5, 10]);
38 /// let b = con.insert(&[5, 20]);
39 ///
40 /// assert_eq!(con.next(a), Some(b));
41 /// assert_eq!(con.next(b), None);
42 /// ```
43 ///
44 /// See also [`TrailTree::prev`].
45 pub fn next(&self, id:usize) -> Option<usize>
46 {
47 self.traverse(id, true)
48 }
49
50 fn traverse(&self, id:usize, next:bool) -> Option<usize>
51 {
52 let forward = if next { 2 } else { 0 };
53 let back = if next { 0 } else { 2 };
54
55 if id < self.cells.len() && let Some(node) = self.node(id) {
56 let rel = node.rel;
57
58 if rel.child[forward] != usize::MAX {
59 // Get forward child's extreme descendant in back direction.
60 let mut current = rel.child[forward];
61
62 while let Some(node) = self.node(current) && node.rel.child[back] != usize::MAX {
63 current = node.rel.child[back];
64 }
65
66 Some(current)
67 } else {
68 // Bubble up until node enters from back direction.
69 let mut last = id;
70 let mut current = rel.parent;
71
72 while current != usize::MAX && let Some(node) = self.node(current) && node.rel.child[forward] == last {
73 last = current;
74 current = node.rel.parent;
75 }
76
77 if current != usize::MAX {
78 Some(current)
79 } else {
80 None
81 }
82 }
83 } else {
84 None
85 }
86 }
87
88 /// Returns the parent of the specified element or None if a root.
89 ///
90 /// # Examples
91 ///
92 /// ```
93 /// use trailtree::TrailTree;
94 ///
95 /// let mut con = TrailTree::<u32,()>::new();
96 ///
97 /// let leaf = con.insert(&[1, 2]);
98 ///
99 /// let mid = con.search(&[1]);
100 /// assert!(mid.is_some());
101 ///
102 /// assert_eq!(mid, con.parent(leaf));
103 /// assert_eq!(None, con.parent(mid.unwrap()));
104 /// ```
105 ///
106 /// See also [`TrailTree::first`], [`TrailTree::last`].
107 pub fn parent(&self, id:usize) -> Option<usize>
108 {
109 if id < self.cells.len() && let Cell::Node(node) = &self.cells[id] {
110 if node.rel.root != usize::MAX {
111 Some(node.rel.root)
112 } else {
113 None
114 }
115 } else {
116 None
117 }
118 }
119
120 /// Returns the first element in the specified element's subtree.
121 /// If no element is specified, the first root element is returned.
122 ///
123 /// # Examples
124 ///
125 /// ```
126 /// use trailtree::TrailTree;
127 ///
128 /// let mut con = TrailTree::<u32,()>::new();
129 ///
130 /// assert_eq!(con.first(None), None);
131 ///
132 /// let a = con.insert(&[1]);
133 /// let b = con.insert(&[1, 4]);
134 /// con.insert(&[1, 8]);
135 /// con.insert(&[2, 3]);
136 ///
137 /// assert_eq!(con.first(None), Some(a));
138 /// assert_eq!(con.first(Some(a)), Some(b));
139 /// ```
140 ///
141 /// See also [`TrailTree::last`], [`TrailTree::parent`].
142 pub fn first(&self, id:Option<usize>) -> Option<usize>
143 {
144 self.extent(id, false)
145 }
146
147 /// Returns the last element in the specified element's subtree.
148 /// If no element is specified, the last root element is returned.
149 ///
150 /// # Examples
151 ///
152 /// ```
153 /// use trailtree::TrailTree;
154 ///
155 /// let mut con = TrailTree::<u32,()>::new();
156 ///
157 /// assert_eq!(con.last(None), None);
158 ///
159 /// let a = con.insert(&[1]);
160 /// con.insert(&[1, 4]);
161 /// let b = con.insert(&[1, 8]);
162 /// let c = con.insert(&[2]);
163 ///
164 /// assert_eq!(con.last(None), Some(c));
165 /// assert_eq!(con.last(Some(a)), Some(b));
166 /// ```
167 ///
168 /// See also [`TrailTree::first`], [`TrailTree::parent`].
169 pub fn last(&self, id:Option<usize>) -> Option<usize>
170 {
171 self.extent(id, true)
172 }
173
174 fn extent(&self, id:Option<usize>, end:bool) -> Option<usize>
175 {
176 let dir = if end { 2 } else { 0 };
177
178 let mut current = if let Some(id) = id {
179 self.rel(id).child[1]
180 } else {
181 self.root
182 };
183
184 while current != usize::MAX && let Some(node) = self.node(current) && node.rel.child[dir] != usize::MAX {
185 current = node.rel.child[dir];
186 }
187
188 if current != usize::MAX {
189 Some(current)
190 } else {
191 None
192 }
193 }
194}