1use std::mem;
4use std::cmp;
5
6use Node;
7use NodeMut;
8
9#[derive(Clone, Copy, Debug, PartialEq, Eq)]
10pub enum Level {
11 Balanced(u32),
12 Imbalanced(u32),
13}
14
15impl Level {
16 pub fn is_balanced(self) -> bool {
17 if let Level::Balanced(_) = self {
18 true
19 } else {
20 false
21 }
22 }
23
24 pub fn as_u32(self) -> u32 {
25 match self {
26 Level::Balanced(e) |
27 Level::Imbalanced(e) => e,
28 }
29 }
30}
31
32pub fn compute_level<N: Node>(node: &N, tolerance: u32) -> Level {
39 use test::Level::*;
40
41 let llevel = node.left().map_or(Balanced(0), |n| compute_level(n, tolerance));
42 let rlevel = node.right().map_or(Balanced(0), |n| compute_level(n, tolerance));
43
44 if llevel.is_balanced() && rlevel.is_balanced() {
45 let max = cmp::max(llevel.as_u32(), rlevel.as_u32());
46 let min = cmp::min(llevel.as_u32(), rlevel.as_u32());
47 if max - min > tolerance {
48 Imbalanced(max + 1)
49 } else {
50 Balanced(max + 1)
51 }
52 } else {
53 Imbalanced(cmp::max(llevel.as_u32(), rlevel.as_u32()) + 1)
54 }
55}
56
57#[derive(Debug)]
58pub struct TestNode<T> {
65 pub val: T,
66 pub left: Option<Box<TestNode<T>>>,
67 pub right: Option<Box<TestNode<T>>>,
68}
69
70impl<T> TestNode<T> {
71 pub fn new(val: T) -> TestNode<T> {
72 TestNode {
73 val: val,
74 left: None,
75 right: None,
76 }
77 }
78}
79
80impl<T> Node for TestNode<T> {
81 type Value = T;
82
83 fn left(&self) -> Option<&Self> {
84 self.left.as_ref().map(|st| &**st)
85 }
86
87 fn right(&self) -> Option<&Self> {
88 self.right.as_ref().map(|st| &**st)
89 }
90
91 fn value(&self) -> &T {
92 &self.val
93 }
94}
95
96impl<T> NodeMut for TestNode<T> {
97 type NodePtr = Box<TestNode<T>>;
98
99 fn detach_left(&mut self) -> Option<Self::NodePtr> {
100 self.left.take()
101 }
102
103 fn detach_right(&mut self) -> Option<Self::NodePtr> {
104 self.right.take()
105 }
106
107 fn insert_left(&mut self, mut st: Option<Self::NodePtr>) -> Option<Self::NodePtr> {
108 mem::swap(&mut self.left, &mut st);
109 st
110 }
111
112 fn insert_right(&mut self, mut st: Option<Self::NodePtr>) -> Option<Self::NodePtr> {
113 mem::swap(&mut self.right, &mut st);
114 st
115 }
116
117 fn value_mut(&mut self) -> &mut T {
118 &mut self.val
119 }
120
121 fn into_parts(self) -> (T, Option<Self::NodePtr>, Option<Self::NodePtr>) {
122 (self.val, self.left, self.right)
123 }
124
125 fn left_mut(&mut self) -> Option<&mut Self> {
126 self.left.as_mut().map(|l| &mut **l)
127 }
128
129 fn right_mut(&mut self) -> Option<&mut Self> {
130 self.right.as_mut().map(|r| &mut **r)
131 }
132}
133
134#[cfg(test)]
135mod tests {
136 use super::TestNode;
137 use Node;
138 use NodeMut;
139
140 fn new_node<T>(val: T) -> Box<TestNode<T>> {
141 Box::new(TestNode::new(val))
142 }
143
144 fn test_tree() -> TestNode<u32> {
145 TestNode {
146 val: 20,
147 left: Some(new_node(10)),
148 right: Some(Box::new(TestNode {
149 val: 30,
150 left: Some(new_node(25)),
151 right: None,
152 })),
153 }
154 }
155
156 #[test]
157 fn rotate() {
158 let mut tt = test_tree();
159
160 tt.rotate_left().unwrap();
161 assert_eq!(*tt.value(), 30);
162 assert_eq!(tt.left.as_ref().unwrap().val, 20);
163 assert_eq!(tt.left.as_ref().unwrap()
164 .left.as_ref().unwrap().val, 10);
165 assert_eq!(tt.left.as_ref().unwrap()
166 .right.as_ref().unwrap().val, 25);
167
168 tt.rotate_right().unwrap();
169 assert_eq!(*tt.value(), 20);
170 assert_eq!(tt.left.as_ref().unwrap().val, 10);
171 assert_eq!(tt.right.as_ref().unwrap().val, 30);
172 assert_eq!(tt.right.as_ref().unwrap()
173 .left.as_ref().unwrap().val, 25);
174 }
175
176 #[test]
177 fn walk() {
178 use WalkAction::*;
179
180 let mut tt = test_tree();
181 let mut steps = vec![Right, Left, Stop];
182 {
183 let mut step_iter = steps.drain(..);
184 tt.walk_reshape(|_| step_iter.next().unwrap(),
185 |st| assert_eq!(st.val, 25),
186 |st, action| {
187 match action {
188 Right => assert_eq!(st.val, 20),
189 Left => assert_eq!(st.val, 30),
190 Stop => unreachable!(),
191 }
192 });
193 }
194 assert_eq!(steps.len(), 0);
195 }
196
197 #[test]
198 fn remove() {
199 let mut tt = test_tree();
200 let tn = tt.right.as_mut().unwrap().try_remove(|_, _| ());
201 assert_eq!(tn.unwrap().value(), &30);
202 assert_eq!(tt.right.as_ref().unwrap().value(), &25);
203 let mut tt2 = test_tree();
204 {
205 let right = tt2.right.as_mut().unwrap();
206 right.right = Some(new_node(40));
207 }
208 let tn = tt2.right.as_mut().unwrap().try_remove(|_, _| ());
209 assert_eq!(tn.unwrap().value(), &30);
210 assert_eq!(tt.right.as_ref().unwrap().value(), &25);
211 }
212
213 #[test]
214 fn stack_blow() {
215 use iter::IntoIter;
216 let mut pt = new_node(20);
217 for _ in 0..200000 {
218 let mut pt2 = new_node(20);
219 pt2.insert_left(Some(pt));
220 pt = pt2;
221 }
222 let _: IntoIter<TestNode<_>> = IntoIter::new(Some(pt));
224 }
225}