extsort_iter/merge/
array_node.rs1use super::previous_power_of_two;
2
3#[derive(Clone, Copy)]
4pub struct Winner {
5 pub idx: u32,
6}
7
8#[derive(Copy, Clone)]
13pub struct TreeNode {
14 pub idx: usize,
15}
16impl TreeNode {
17 pub fn left(self) -> Self {
18 Self {
19 idx: self.idx * 2 + 1,
20 }
21 }
22 pub fn right(self) -> Self {
23 Self {
24 idx: self.idx * 2 + 2,
25 }
26 }
27 pub fn parent(self) -> Self {
28 Self {
29 idx: self.idx.saturating_sub(1) / 2,
30 }
31 }
32 pub fn root() -> Self {
33 Self { idx: 0 }
34 }
35 pub fn is_root(&self) -> bool {
36 self.idx == 0
37 }
38
39 pub fn leaf_for_winner(leaf: Winner, tree_size: usize) -> Self {
42 let full_level_size = previous_power_of_two(tree_size);
43 let overhang = (tree_size - full_level_size) * 2;
44
45 let leaf_idx = leaf.idx as usize;
46
47 let tree_idx = if leaf_idx < overhang {
48 full_level_size * 2 - 1 + leaf_idx
51 } else {
52 let overhang_compensation = overhang / 2;
59
60 full_level_size - 1 - overhang_compensation + leaf_idx
61 };
62
63 Self { idx: tree_idx }
64 }
65}
66
67#[cfg(test)]
68mod test {
69 use crate::merge::array_node::{TreeNode, Winner};
70
71 #[test]
72 fn test_leaf_calculation() {
73 fn run_test(expected_values: &[usize]) {
74 let tree_size = expected_values.len() as u32;
75 let values: Vec<_> = (0..tree_size)
76 .map(|leaf| TreeNode::leaf_for_winner(Winner { idx: leaf }, tree_size as usize).idx)
77 .collect();
78 assert_eq!(expected_values, values);
79 }
80 run_test(&[1, 2]);
81 run_test(&[3, 4, 2]);
82 run_test(&[3, 4, 5, 6]);
83 run_test(&[7, 8, 4, 5, 6]);
84 run_test(&[7, 8, 9, 10, 5, 6]);
85 run_test(&[7, 8, 9, 10, 11, 12, 6]);
86 run_test(&[7, 8, 9, 10, 11, 12, 13, 14]);
87 run_test(&[15, 16, 8, 9, 10, 11, 12, 13, 14]);
88 }
89
90 #[test]
91 fn test_clone_to_make_coverage_happy() {
92 let _ = Winner { idx: 0 };
93 let _ = TreeNode { idx: 0 };
94 }
95}