1use alloc::vec::Vec;
2use bitstring::BitString;
3
4use crate::walk_mut::NodeOrTree;
5
6use super::{
7 goto::{
8 GotoStepResult,
9 NodeRef,
10 },
11 InsertPosition,
12 Node,
13 Tree,
14 TreeProperties,
15 WalkedDirection,
16};
17
18pub struct Walk<'r, TP: TreeProperties, D = (), A = ()> {
24 tree: Option<&'r Node<TP>>,
25 stack: Vec<(&'r Node<TP>, (D, A))>,
26}
27
28impl<'r, TP: TreeProperties, D, A> Walk<'r, TP, D, A> {
29 pub(in crate::tree) fn new(tree: &'r Tree<TP>) -> Self {
30 Self {
31 tree: tree.node.as_ref(),
32 stack: Vec::new(),
33 }
34 }
35
36 pub fn up(&mut self) -> Option<D> {
38 Some(self.stack.pop()?.1 .0)
39 }
40
41 pub fn up_with(&mut self) -> Option<(D, A)> {
43 Some(self.stack.pop()?.1)
44 }
45
46 pub fn current(&self) -> NodeOrTree<Option<&'r Node<TP>>, &'r Node<TP>> {
48 match self.stack.last() {
49 Some(&(node, _)) => NodeOrTree::Node(node),
50 None => NodeOrTree::Tree(self.tree),
51 }
52 }
53}
54
55impl<'r, TP: TreeProperties, D, A> Walk<'r, TP, D, A>
56where
57 D: From<WalkedDirection>,
58{
59 pub fn down_root_with(&mut self, add: A) -> bool {
61 if self.stack.is_empty() {
62 if let Some(root) = self.tree {
63 self.stack.push((root, (WalkedDirection::Down.into(), add)));
64 return true;
65 }
66 }
67 false
68 }
69
70 pub fn down_left_with(&mut self, add: A) -> bool {
72 self.down_with(false, add)
73 }
74
75 pub fn down_right_with(&mut self, add: A) -> bool {
77 self.down_with(true, add)
78 }
79
80 pub fn down_with(&mut self, side: bool, add: A) -> bool {
84 if let Some(&(node, _)) = self.stack.last() {
85 if let Some(child) = node.get_child(side) {
86 self.stack
87 .push((child, (WalkedDirection::from_side(side).into(), add)));
88 return true;
89 }
90 }
91 false
92 }
93}
94
95impl<'r, TP: TreeProperties, D> Walk<'r, TP, D, ()>
96where
97 D: From<WalkedDirection>,
98{
99 pub fn down_root(&mut self) -> bool {
101 self.down_root_with(())
102 }
103
104 pub fn down_left(&mut self) -> bool {
106 self.down_left_with(())
107 }
108
109 pub fn down_right(&mut self) -> bool {
111 self.down_right_with(())
112 }
113
114 pub fn down(&mut self, side: bool) -> bool {
118 self.down_with(side, ())
119 }
120}
121
122impl<'r, TP: TreeProperties, D> Walk<'r, TP, D>
123where
124 D: From<WalkedDirection>,
125{
126 fn goto_clean(&mut self, key: &TP::Key) {
128 let key_len = key.len();
129 while let Some(&(node, _)) = self.stack.last() {
130 if node._is_prefix_of(key, key_len) {
131 return;
132 }
133 self.stack.pop();
134 }
135 }
136
137 fn goto_insert_step(
139 &mut self,
140 key: &TP::Key,
141 key_len: usize,
142 ) -> Result<(), Option<InsertPosition>> {
143 if let Some(&(node, _)) = self.stack.last() {
144 match node.goto_insert_step(key, key_len) {
145 GotoStepResult::Final(r) => Err(Some(r.into())),
146 GotoStepResult::Continue(node, dir) => {
147 self.stack.push((node, (dir.into(), ())));
148 Ok(())
149 },
150 }
151 } else if let Some(root) = self.tree {
152 self.stack.push((root, (WalkedDirection::Down.into(), ())));
153 Ok(())
154 } else {
155 Err(None)
156 }
157 }
158
159 fn goto_insert_down(&mut self, key: &TP::Key) -> Option<InsertPosition> {
161 let key_len = key.len();
162 loop {
163 match self.goto_insert_step(key, key_len) {
164 Ok(()) => (), Err(r) => return r, }
167 }
168 }
169
170 pub fn goto_insert(&mut self, key: &TP::Key) -> Option<InsertPosition> {
178 self.goto_clean(key);
179 self.goto_insert_down(key)
180 }
181}
182
183impl<'r, TP: TreeProperties> Walk<'r, TP, WalkedDirection> {
184 pub fn next_pre_order(&mut self) -> Option<&'r Node<TP>> {
186 match self.current() {
187 NodeOrTree::Tree(_) => {
188 self.down_root();
189 },
190 NodeOrTree::Node(node) => {
191 if node.is_leaf() {
192 loop {
193 match self.up()? {
194 WalkedDirection::Down => {
195 return None;
196 }, WalkedDirection::Left => {
198 self.down_right();
199 break;
200 },
201 WalkedDirection::Right => (), }
203 }
204 } else {
205 self.down_left();
206 }
207 },
208 }
209 return self.current().node();
210 }
211
212 pub fn next_in_order(&mut self) -> Option<&'r Node<TP>> {
214 match self.current() {
215 NodeOrTree::Tree(_) => {
216 self.down_root();
217 while self.down_left() {}
218 },
219 NodeOrTree::Node(node) => {
220 if node.is_leaf() {
221 loop {
222 match self.up()? {
223 WalkedDirection::Down => {
224 return None;
225 }, WalkedDirection::Left => {
227 break;
228 },
229 WalkedDirection::Right => (), }
231 }
232 } else {
233 self.down_right();
234 while self.down_left() {}
235 }
236 },
237 }
238 return self.current().node();
239 }
240
241 pub fn next_leaf(&mut self) -> Option<&'r Node<TP>> {
243 match self.current() {
244 NodeOrTree::Tree(_) => {
245 self.down_root();
246 while self.down_left() {}
247 },
248 NodeOrTree::Node(_) => {
249 loop {
250 match self.up()? {
251 WalkedDirection::Down => {
252 return None; },
254 WalkedDirection::Left => {
255 self.down_right();
256 while self.down_left() {}
257 break;
258 },
259 WalkedDirection::Right => (), }
261 }
262 },
263 }
264 return self.current().node();
265 }
266
267 pub fn next_post_order(&mut self) -> Option<&'r Node<TP>> {
269 match self.current() {
270 NodeOrTree::Tree(_) => {
271 self.down_root();
272 while self.down_left() {}
273 },
274 NodeOrTree::Node(_) => {
275 match self.up()? {
276 WalkedDirection::Down => {
277 return None;
278 }, WalkedDirection::Left => {
280 self.down_right();
281 while self.down_left() {}
282 },
283 WalkedDirection::Right => (),
284 }
285 },
286 }
287 return self.current().node();
288 }
289}