transact/scheduler/parallel/
tree.rs1use std::cell::RefCell;
2use std::collections::BTreeMap;
3use std::collections::VecDeque;
4use std::error::Error as StdError;
5use std::rc::Rc;
6
7#[derive(Debug)]
8pub enum RadixTreeError {
9 AddressNotInTree(String),
10}
11
12impl StdError for RadixTreeError {
13 fn description(&self) -> &str {
14 match *self {
15 RadixTreeError::AddressNotInTree(ref msg) => msg,
16 }
17 }
18}
19
20impl std::fmt::Display for RadixTreeError {
21 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
22 match *self {
23 RadixTreeError::AddressNotInTree(ref s) => write!(f, "AddressNotInTree: {}", s),
24 }
25 }
26}
27
28#[derive(Debug, Clone, Default)]
29pub struct Node<T> {
30 address: String,
31 children: BTreeMap<String, Rc<RefCell<Node<T>>>>,
32 data: Option<T>,
33}
34
35#[derive(Default, Debug, Clone)]
36pub struct RadixTree<T> {
37 root: Rc<RefCell<Node<T>>>,
38}
39
40impl<T: Clone> RadixTree<T> {
43 pub fn new() -> Self {
44 RadixTree {
45 root: Rc::new(RefCell::new(Node {
46 address: "".to_string(),
47 children: BTreeMap::new(),
48 data: None,
49 })),
50 }
51 }
52
53 fn get_child(
54 node: &Rc<RefCell<Node<T>>>,
55 address: &str,
56 ) -> Result<Rc<RefCell<Node<T>>>, RadixTreeError> {
57 node.borrow()
58 .children
59 .values()
60 .find(|child| address.starts_with(&child.borrow().address))
61 .map(Rc::clone)
62 .ok_or_else(|| RadixTreeError::AddressNotInTree("Address Not In Tree".to_string()))
63 }
64
65 fn walk_to_address(&self, address: &str) -> Vec<Rc<RefCell<Node<T>>>> {
67 let mut current_node = Rc::clone(&self.root);
68 let mut results = vec![Rc::clone(¤t_node)];
69
70 while address != current_node.borrow().address.as_str()
72 && address.starts_with(current_node.borrow().address.as_str())
73 {
74 match RadixTree::get_child(¤t_node, address) {
75 Ok(child) => {
76 results.push(Rc::clone(&child));
77 current_node = child;
78 }
79 Err(_) => break,
80 }
81 }
82 results
83 }
84
85 pub fn walk(&self, address: &str) -> Vec<(String, Option<T>)> {
90 let mut return_nodes = Vec::new();
91 let accumulated_nodes = self.walk_to_address(address);
92 for node in accumulated_nodes.iter() {
93 return_nodes.push((node.borrow().address.clone(), node.borrow().data.clone()));
94 }
95
96 if let Some(node) = accumulated_nodes.iter().last() {
97 let mut to_process = VecDeque::new();
98 let descendants = node.borrow().children.clone();
99 for descendant in descendants.values() {
100 to_process.push_front(Rc::clone(descendant));
101 }
102 while let Some(current_child) = to_process.pop_front() {
103 return_nodes.push((
104 current_child.borrow().address.clone(),
105 current_child.borrow().data.clone(),
106 ));
107 let additional_descendants = ¤t_child.borrow().children;
108 for child in additional_descendants.values() {
109 to_process.push_front(Rc::clone(child));
110 }
111 }
112 }
113 return_nodes
114 }
115
116 fn get_or_create(&self, address: &str) -> Rc<RefCell<Node<T>>> {
119 let accumulated_nodes = self.walk_to_address(address);
120 let first_ancestor = accumulated_nodes
121 .iter()
122 .last()
123 .expect("Node ancestors not formed correctly");
124
125 if first_ancestor.borrow().address == address {
126 return Rc::clone(first_ancestor);
127 }
128
129 let new_node = Rc::new(RefCell::new(Node {
131 address: address.to_string(),
132 children: BTreeMap::new(),
133 data: None,
134 }));
135
136 let prefix_len = first_ancestor.borrow().address.len();
138 let option_ancestor_child = first_ancestor
139 .borrow()
140 .children
141 .values()
142 .find(|child| {
143 let child_address = &child.borrow().address;
144 let child_address_prefix: String =
145 child_address.chars().skip(prefix_len).collect::<String>();
146 let address_prefix: String =
147 address.chars().skip(prefix_len).take(1).collect::<String>();
148 child_address_prefix.starts_with(&address_prefix)
149 })
150 .map(Rc::clone);
151
152 let ancestor_child = match option_ancestor_child {
155 Some(child) => child,
156 None => {
157 first_ancestor
158 .borrow_mut()
159 .children
160 .insert(address.to_string(), Rc::clone(&new_node));
161 return new_node;
162 }
163 };
164
165 if ancestor_child.borrow().address.starts_with(address) {
168 first_ancestor
169 .borrow_mut()
170 .children
171 .insert(address.to_string(), Rc::clone(&new_node));
172
173 new_node
174 .borrow_mut()
175 .children
176 .insert(address.to_string(), Rc::clone(&ancestor_child));
177 first_ancestor
178 .borrow_mut()
179 .children
180 .remove(&ancestor_child.borrow().address);
181 return new_node;
182 };
183
184 let ancestor_child_address = ancestor_child.borrow().address.clone();
188 let shorter = if address.len() < ancestor_child_address.len() {
189 address
190 } else {
191 &ancestor_child_address
192 };
193 let intermediate_node = Rc::new(RefCell::new(Node {
194 address: String::from(""),
195 children: BTreeMap::new(),
196 data: None,
197 }));
198
199 for i in 0..shorter.len() {
200 if address.chars().nth(i) != ancestor_child_address.chars().nth(i) {
201 intermediate_node.borrow_mut().address = shorter[..i].to_string();
202 break;
203 }
204 }
205 let mut new_children_map = BTreeMap::new();
206 new_children_map.insert(new_node.borrow().address.clone(), Rc::clone(&new_node));
207 new_children_map.insert(
208 ancestor_child.borrow().address.clone(),
209 Rc::clone(&ancestor_child),
210 );
211 intermediate_node
212 .borrow_mut()
213 .children
214 .append(&mut new_children_map);
215 first_ancestor.borrow_mut().children.insert(
216 intermediate_node.borrow().address.clone(),
217 Rc::clone(&intermediate_node),
218 );
219 first_ancestor
220 .borrow_mut()
221 .children
222 .remove(&ancestor_child.borrow().address.clone());
223
224 new_node
225 }
226
227 pub fn update(&self, address: &str, updater: &dyn Fn(Option<T>) -> Option<T>, prune: bool) {
230 let node = self.get_or_create(address);
231 let existing_data = node.borrow_mut().data.take();
232 node.borrow_mut().data = updater(existing_data);
233
234 if prune {
235 node.borrow_mut().children.clear();
236 }
237 }
238
239 pub fn prune(&self, address: &str) {
241 let accumulated_nodes = self.walk_to_address(address);
242 if let Some(node) = accumulated_nodes.iter().last() {
243 node.borrow_mut().children.clear()
244 }
245 }
246}
247
248#[cfg(test)]
249mod tests {
250 use super::*;
251
252 #[test]
253 fn tree_creation() {
254 let tree: RadixTree<i32> = RadixTree::new();
255 assert_eq!(tree.root.borrow().children.len(), 0);
256 assert_eq!(tree.root.borrow().address, "".to_string());
257 }
258
259 #[test]
260 fn tree_insert_children() {
261 let tree: RadixTree<i32> = RadixTree::new();
271 tree.get_or_create("radix");
272 tree.get_or_create("radish");
273 tree.get_or_create("radon");
274
275 assert_eq!(tree.root.borrow().children.len(), 1);
276
277 let found_node_rad = tree.get_or_create("rad");
278 assert_eq!(found_node_rad.borrow().address, "rad".to_string());
279 assert_eq!(found_node_rad.borrow().children.len(), 2);
280
281 let found_node_radi = tree.get_or_create("radi");
282 assert_eq!(found_node_radi.borrow().address, "radi".to_string());
283 assert_eq!(found_node_radi.borrow().children.len(), 2);
284
285 let found_node_radix = tree.get_or_create("radix");
286 assert_eq!(found_node_radix.borrow().address, "radix".to_string());
287 assert_eq!(found_node_radix.borrow().children.len(), 0);
288
289 let found_node_radish = tree.get_or_create("radish");
290 assert_eq!(found_node_radish.borrow().address, "radish".to_string());
291 assert_eq!(found_node_radish.borrow().children.len(), 0);
292
293 let found_node_radon = tree.get_or_create("radon");
294 assert_eq!(found_node_radon.borrow().address, "radon".to_string());
295 assert_eq!(found_node_radon.borrow().children.len(), 0);
296 }
297
298 #[test]
299 fn tree_walk_to_address() {
300 let tree: RadixTree<i32> = RadixTree::new();
310 tree.get_or_create("radix");
311 tree.get_or_create("radish");
312 tree.get_or_create("radon");
313
314 let walk_to_results_rad = tree.walk_to_address("rad");
315 assert_eq!(walk_to_results_rad.len(), 2);
316
317 let walk_to_results_radon = tree.walk_to_address("radon");
318 assert_eq!(walk_to_results_radon.len(), 3);
319
320 let walk_to_results_radix = tree.walk_to_address("radix");
321 assert_eq!(walk_to_results_radix.len(), 4);
322 }
323
324 #[test]
325 fn tree_walk() {
326 let tree: RadixTree<i32> = RadixTree::new();
336 tree.get_or_create("radix");
337 tree.get_or_create("radish");
338 tree.get_or_create("radon");
339
340 let walk_results_radix = tree.walk("radix");
341 assert_eq!(walk_results_radix.len(), 4);
342 assert!(walk_results_radix.contains(&("radix".to_string(), None)));
343
344 let walk_results_rad = tree.walk("rad");
345 assert_eq!(walk_results_rad.len(), 6);
346 assert!(walk_results_rad.contains(&("rad".to_string(), None)));
347 }
348
349 fn update_data(data: Option<i32>) -> Option<i32> {
350 if data.is_none() {
351 return Some(1);
352 } else {
353 return Some(data.unwrap() + 1);
354 }
355 }
356
357 #[test]
358 fn tree_node_update() {
359 let tree: RadixTree<i32> = RadixTree::new();
369 tree.get_or_create("radix");
370 tree.get_or_create("radish");
371 tree.get_or_create("radon");
372
373 tree.update("radix", &update_data, false);
374 let updated_node = tree.get_or_create("radix");
375 assert_eq!(updated_node.borrow().data, Some(1));
376 tree.update("radix", &update_data, false);
377 assert_eq!(updated_node.borrow().data, Some(2));
378 }
379
380 #[test]
381 fn tree_prune() {
382 let tree: RadixTree<i32> = RadixTree::new();
392 tree.get_or_create("radix");
393 tree.get_or_create("radish");
394 tree.get_or_create("radon");
395
396 tree.prune("rad");
397 let parent_node = tree.get_or_create("rad");
398 let mut parent_node_walk = tree.walk("rad");
399
400 assert_eq!(parent_node.borrow().children.len(), 0);
401 assert!(!parent_node_walk.contains(&("radi".to_string(), None)));
402 assert!(parent_node_walk.contains(&("rad".to_string(), None)));
403
404 tree.get_or_create("radish");
405 tree.get_or_create("radix");
406 parent_node_walk = tree.walk("rad");
407
408 assert_eq!(parent_node.borrow().children.len(), 1);
409 assert!(parent_node_walk.contains(&("radix".to_string(), None)));
410 assert!(parent_node_walk.contains(&("radish".to_string(), None)));
411 }
412}