1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use super::*;
use vector::tear_down::{NodeRecord, NodeRecordStack, BLANK};
pub fn tear_down(prism: AnchoredLine, has_vals: u32) {
assert_eq!(0, prism.segment().anchor().aliases());
let guide = Guide::hydrate(prism);
let (child_count, key_count) = {
let p = Pop::from(guide.root[-1]);
(p.child_count(), p.key_count())
};
guide.root.offset((child_count << 1) as i32).span(key_count << has_vals).retire();
let stack_space = [BLANK; 8];
let mut stack = NodeRecordStack::new(stack_space.as_ptr());
stack.push(NodeRecord {
first_child: guide.root,
child_count,
height: 0,
on_boundary: false,
current_child: None,
});
while !stack.is_empty() {
step(&mut stack, has_vals);
}
Segment::free(guide.segment());
}
pub fn step(stack: &mut NodeRecordStack, has_vals: u32) {
let top = stack.top();
if top.height == MAX_LEVELS - 1 {
collision_children(top, has_vals);
stack.pop();
return;
}
let search_from = match top.current_child {
Some(i) => {
let idx = (i << 1) as i32;
let s = top.first_child[idx + 1].segment();
Segment::free(s);
i + 1
},
None => { 0 },
};
let mut i = search_from;
let cap = top.child_count;
while i < cap {
let idx = (i << 1) as i32;
let c = top.first_child[idx + 1].segment();
if c.unalias() == 0 {
let (child_count, key_count) = {
let p = Pop::from(top.first_child[idx]);
(p.child_count(), p.key_count())
};
c.line_at(child_count << 1).span(key_count << has_vals).retire();
if child_count == 0 {
Segment::free(c);
} else {
top.current_child = Some(i);
stack.push(NodeRecord {
first_child: c.line_at(0),
child_count,
height: top.height + 1,
on_boundary: false,
current_child: None,
});
return;
}
}
i = i + 1;
}
stack.pop();
}
pub fn collision_children(node: &NodeRecord, has_vals: u32) {
for i in 0..node.child_count {
let idx = (i << 1) as i32;
let key_count = node.first_child[idx].u32();
let c = node.first_child[idx + 1].segment();
if c.unalias() == 0 {
c.at(0..(key_count << has_vals)).retire();
Segment::free(c);
}
}
}