1
2pub mod signed;
3
4use std::cmp;
5
6const RADIX: usize = 4;
8
9#[derive(Debug, Clone)]
10pub struct Node {
11 idx: u32,
12 parent: Option<u32>,
13 children: [Option<u32>; RADIX],
14 leaves: (u32, u32),
16 nb_tree_leaves: u32,
17 level: u32,
18}
19
20impl Node {
21 #[allow(clippy::arithmetic_side_effects)]
23 fn new_leaf(idx: usize, nb_tree_leaves: usize) -> Node {
24 let idx = u32::try_from(idx).expect("leaf index fits in u32");
25 let nb_tree_leaves = u32::try_from(nb_tree_leaves).expect("leaf count fits in u32");
26 Node {
27 idx,
28 parent: None,
29 children: [None; RADIX],
30 leaves: (idx, (idx+1) % nb_tree_leaves),
31 nb_tree_leaves,
32 level: 0,
33 }
34 }
35
36 pub fn idx(&self) -> usize {
37 self.idx as usize
38 }
39
40 pub fn internal_idx(&self) -> usize {
44 self.idx.checked_sub(self.nb_tree_leaves)
45 .expect("called internal_idx on leaf node") as usize
46 }
47
48 pub fn parent(&self) -> Option<usize> {
49 self.parent.map(|p| p as usize)
50 }
51
52 pub fn children(&self) -> impl Iterator<Item = usize> {
53 self.children.clone().into_iter().filter_map(|c| c).map(|c| c as usize)
54 }
55
56 pub fn level(&self) -> usize {
58 self.level as usize
59 }
60
61 pub fn internal_level(&self) -> usize {
67 self.level.checked_sub(1).expect("called internal_level on leaf node") as usize
68 }
69
70 #[allow(clippy::arithmetic_side_effects)]
72 pub fn leaves(&self) -> impl Iterator<Item = usize> + Clone {
73 let (first, last) = self.leaves;
74 let nb = self.nb_tree_leaves;
75 (first..)
76 .take(nb as usize)
77 .map(move |e| e % nb)
78 .take_while(move |e| first == last || *e != last)
79 .map(|e| e as usize)
80 }
81
82 pub fn is_leaf(&self) -> bool {
83 self.children.iter().all(|o| o.is_none())
84 }
85
86 pub fn is_root(&self) -> bool {
87 self.parent.is_none()
88 }
89}
90
91#[derive(Debug, Clone)]
95pub struct Tree {
96 nodes: Vec<Node>,
99 nb_leaves: usize,
100}
101
102impl Tree {
103 #[allow(clippy::arithmetic_side_effects)]
107 pub fn nb_nodes_for_leaves(nb_leaves: usize) -> usize {
108 let mut ret = nb_leaves;
109 let mut left = nb_leaves;
110 while left > 1 {
111 let radix = cmp::min(left, RADIX);
112 left -= radix;
113 left += 1;
114 ret += 1;
115 }
116 ret
117 }
118
119 #[allow(clippy::arithmetic_side_effects)]
121 pub fn new(
122 nb_leaves: usize,
123 ) -> Tree {
124 assert_ne!(nb_leaves, 0, "trees can't be empty");
125
126 let mut nodes = Vec::with_capacity(Tree::nb_nodes_for_leaves(nb_leaves));
127
128 nodes.extend((0..nb_leaves).map(|i| Node::new_leaf(i, nb_leaves)));
130
131 let mut cursor = 0;
132 while cursor < nodes.len() - 1 {
135 let mut children = [None; RADIX];
136 let mut nb_children = 0;
137 let mut max_child_level = 0;
138 while cursor < nodes.len() && nb_children < RADIX {
139 children[nb_children] = Some(u32::try_from(cursor).expect("node index fits in u32"));
140
141 let new_idx = nodes.len(); let child = &mut nodes[cursor];
143 child.parent = Some(u32::try_from(new_idx).expect("node index fits in u32"));
144
145 if child.level > max_child_level {
147 max_child_level = child.level;
148 }
149
150 cursor += 1;
151 nb_children += 1;
152 }
153 nodes.push(Node {
154 idx: u32::try_from(nodes.len()).expect("node index fits in u32"),
155 leaves: (
156 nodes[children.first().unwrap().unwrap() as usize].leaves.0,
157 nodes[children.iter().filter_map(|c| *c).last().unwrap() as usize].leaves.1,
158 ),
159 children,
160 level: max_child_level + 1,
161 parent: None,
162 nb_tree_leaves: u32::try_from(nb_leaves).expect("leaf count fits in u32"),
163 });
164 }
165
166 Tree { nodes, nb_leaves }
167 }
168
169 pub fn nb_leaves(&self) -> usize {
170 self.nb_leaves
171 }
172
173 pub fn nb_nodes(&self) -> usize {
174 self.nodes.len()
175 }
176
177 pub fn nb_internal_nodes(&self) -> usize {
179 self.nodes.len().checked_sub(self.nb_leaves)
180 .expect("tree can't have less nodes than leaves")
181 }
182
183 pub fn node_at(&self, node_idx: usize) -> &Node {
184 self.nodes.get(node_idx).expect("node_idx out of bounds")
185 }
186
187 pub fn root(&self) -> &Node {
188 self.nodes.last().expect("no empty trees")
189 }
190
191 pub fn iter(&self) -> std::slice::Iter<'_, Node> {
193 self.nodes.iter()
194 }
195
196 pub fn iter_internal(&self) -> std::slice::Iter<'_, Node> {
199 self.nodes[self.nb_leaves..].iter()
200 }
201
202 pub fn into_iter(self) -> std::vec::IntoIter<Node> {
204 self.nodes.into_iter()
205 }
206
207 pub fn iter_branch(&self, leaf_idx: usize) -> BranchIter<'_> {
210 assert!(leaf_idx < self.nodes.len());
211 BranchIter {
212 tree: &self,
213 cursor: Some(leaf_idx),
214 }
215 }
216
217 pub fn iter_branch_with_output(&self, node_idx: usize) -> BranchWithOutputIter<'_> {
232 assert!(node_idx < self.nodes.len());
233 BranchWithOutputIter {
234 tree: self,
235 prev_idx: node_idx,
236 cursor: self.nodes[node_idx].parent(),
237 }
238 }
239
240 pub fn parent_idx_of(&self, idx: usize) -> Option<usize> {
241 self.nodes.get(idx).and_then(|n| n.parent.map(|c| c as usize))
242 }
243
244 pub fn parent_idx_of_with_sibling_idx(&self, idx: usize) -> Option<(usize, usize)> {
247 self.nodes.get(idx).and_then(|n| n.parent).map(|parent_idx| {
248 let child_idx = self.nodes[parent_idx as usize].children.iter()
249 .position(|c| *c == Some(u32::try_from(idx).expect("node index fits in u32")))
250 .expect("broken tree");
251 (self.nodes[parent_idx as usize].idx as usize, child_idx as usize)
252 })
253 }
254
255}
256
257#[derive(Clone)]
259pub struct BranchIter<'a> {
260 tree: &'a Tree,
261 cursor: Option<usize>,
262}
263
264impl<'a> Iterator for BranchIter<'a> {
265 type Item = &'a Node;
266 fn next(&mut self) -> Option<Self::Item> {
267 if let Some(cursor) = self.cursor {
268 let ret = &self.tree.nodes[cursor];
269 self.cursor = ret.parent();
270 Some(ret)
271 } else {
272 None
273 }
274 }
275}
276
277#[derive(Clone)]
279pub struct BranchWithOutputIter<'a> {
280 tree: &'a Tree,
281 prev_idx: usize,
282 cursor: Option<usize>,
283}
284
285impl<'a> Iterator for BranchWithOutputIter<'a> {
286 type Item = (usize, usize);
287 fn next(&mut self) -> Option<Self::Item> {
288 let cursor = self.cursor?;
289 let node = &self.tree.nodes[cursor];
290 let child_idx = node.children()
291 .position(|c| c == self.prev_idx)
292 .expect("broken tree");
293 self.prev_idx = cursor;
294 self.cursor = node.parent();
295 Some((cursor, child_idx))
296 }
297}
298
299#[cfg(test)]
300mod test {
301 use std::collections::HashSet;
302
303use super::*;
304
305 #[test]
306 fn test_simple_tree() {
307 for n in 1..100 {
308 let tree = Tree::new(n);
309
310 assert!(tree.nodes.iter().rev().skip(1).all(|n| n.parent.is_some()));
311 assert!(tree.nodes.iter().enumerate().skip(tree.nb_leaves).all(|(i, n)| {
312 n.children.iter().filter_map(|v| *v)
313 .all(|c| tree.nodes[c as usize].parent == Some(i as u32))
314 }));
315 assert!(tree.nodes.iter().enumerate().rev().skip(1).all(|(i, n)| {
316 let parent_idx = n.parent.unwrap() as usize;
317 tree.nodes[parent_idx].children.iter().find(|c| **c == Some(i as u32)).is_some()
318 }));
319 assert_eq!(Tree::nb_nodes_for_leaves(n), tree.nb_nodes(), "leaves: {}", n);
320 }
321 }
322
323 #[test]
324 fn test_leaves_range() {
325 for n in 1..42 {
326 let tree = Tree::new(n);
327
328 for node in &tree.nodes[0..tree.nb_leaves()] {
329 assert_eq!(node.leaves().collect::<Vec<_>>(), vec![node.idx()]);
330 }
331 for node in tree.iter() {
332 if !node.is_leaf() {
333 assert_eq!(
334 node.leaves().count(),
335 node.children().map(|c| tree.nodes[c].leaves().count()).sum::<usize>(),
336 "idx: {}", node.idx(),
337 );
338 }
339 assert!(node.leaves().all(|l| l < tree.nb_leaves()));
340 assert_eq!(
341 node.leaves().count(),
342 node.leaves().collect::<HashSet<_>>().len(),
343 );
344 }
345 println!("n={n} ok");
346 }
347 }
348
349 #[test]
350 fn test_iter_branch_with_output() {
351 for n in 1..100 {
352 let tree = Tree::new(n);
353
354 for start_idx in 0..tree.nb_nodes() {
355 let results: Vec<_> = tree.iter_branch_with_output(start_idx).collect();
356
357 assert!(results.iter().all(|(idx, _)| *idx != start_idx));
359
360 let mut expected_parent = tree.nodes[start_idx].parent();
362 for (ancestor_idx, _) in &results {
363 assert_eq!(Some(*ancestor_idx), expected_parent);
364 expected_parent = tree.nodes[*ancestor_idx].parent();
365 }
366
367 let mut prev = start_idx;
369 for (ancestor_idx, child_idx) in &results {
370 let child = tree.nodes[*ancestor_idx].children().nth(*child_idx).unwrap();
371 assert_eq!(child, prev);
372 prev = *ancestor_idx;
373 }
374
375 if let Some((last_idx, _)) = results.last() {
377 assert!(tree.nodes[*last_idx].is_root());
378 }
379
380 let branch_len = tree.iter_branch(start_idx).skip(1).count();
382 assert_eq!(results.len(), branch_len);
383 }
384 }
385 }
386}