simd_intervaltree/
builder.rs1use alloc::vec;
4use alloc::vec::Vec;
5
6use crate::tree::{IntervalTree, Node};
7use crate::Interval;
8
9#[derive(Debug, Clone)]
22pub struct IntervalTreeBuilder<T, V> {
23 intervals: Vec<(Interval<T>, V)>,
24}
25
26impl<T, V> Default for IntervalTreeBuilder<T, V> {
27 fn default() -> Self {
28 Self::new()
29 }
30}
31
32impl<T, V> IntervalTreeBuilder<T, V> {
33 #[must_use]
35 pub fn new() -> Self {
36 Self {
37 intervals: Vec::new(),
38 }
39 }
40
41 #[must_use]
43 pub fn with_capacity(capacity: usize) -> Self {
44 Self {
45 intervals: Vec::with_capacity(capacity),
46 }
47 }
48
49 #[must_use]
51 pub fn insert<R: Into<Interval<T>>>(mut self, range: R, value: V) -> Self {
52 self.intervals.push((range.into(), value));
53 self
54 }
55
56 #[must_use]
58 pub fn len(&self) -> usize {
59 self.intervals.len()
60 }
61
62 #[must_use]
64 pub fn is_empty(&self) -> bool {
65 self.intervals.is_empty()
66 }
67}
68
69impl<T: Ord + Copy, V> IntervalTreeBuilder<T, V> {
70 #[must_use]
76 pub fn build(self) -> IntervalTree<T, V> {
77 let n = self.intervals.len();
78
79 if n == 0 {
80 return IntervalTree {
81 starts: Vec::new(),
82 ends: Vec::new(),
83 values: Vec::new(),
84 nodes: Vec::new(),
85 by_end_indices: Vec::new(),
86 ends_desc: Vec::new(),
87 };
88 }
89
90 let mut input_starts: Vec<T> = Vec::with_capacity(n);
92 let mut input_ends: Vec<T> = Vec::with_capacity(n);
93 let mut input_values: Vec<V> = Vec::with_capacity(n);
94
95 for (interval, value) in self.intervals {
96 input_starts.push(interval.start);
97 input_ends.push(interval.end);
98 input_values.push(value);
99 }
100
101 let indices: Vec<usize> = (0..n).collect();
103 let mut planner = TreePlanner::new(&input_starts, &input_ends);
104 planner.plan_node(&indices);
105
106 let mut starts: Vec<T> = Vec::with_capacity(n);
108 let mut ends: Vec<T> = Vec::with_capacity(n);
109 let mut values: Vec<V> = Vec::with_capacity(n);
110 let mut by_end_indices: Vec<usize> = Vec::with_capacity(n);
111 let mut ends_desc: Vec<T> = Vec::with_capacity(n);
112 let mut nodes: Vec<Node> = Vec::with_capacity(planner.node_intervals.len());
113
114 let mut index_map: Vec<usize> = vec![0; n];
116
117 for node_data in &planner.node_intervals {
118 let node_start_pos = starts.len();
119
120 let mut sorted_indices = node_data.containing.clone();
122 sorted_indices.sort_by_key(|&i| input_starts[i]);
123
124 for &old_idx in &sorted_indices {
125 let new_idx = starts.len();
126 index_map[old_idx] = new_idx;
127 starts.push(input_starts[old_idx]);
128 ends.push(input_ends[old_idx]);
129 }
130
131 let node_end_pos = starts.len();
132
133 let mut by_end = sorted_indices.clone();
136 by_end.sort_by(|&a, &b| input_ends[b].cmp(&input_ends[a]));
137
138 let by_end_begin = by_end_indices.len();
139 for &old_idx in &by_end {
140 by_end_indices.push(index_map[old_idx]);
141 ends_desc.push(input_ends[old_idx]);
142 }
143 let by_end_end = by_end_indices.len();
144
145 let pivot_new_idx = index_map[node_data.pivot_idx];
147
148 nodes.push(Node {
149 pivot_idx: pivot_new_idx,
150 data_begin: node_start_pos,
151 data_end: node_end_pos,
152 by_end_begin,
153 by_end_end,
154 left: node_data.left,
155 right: node_data.right,
156 });
157 }
158
159 let mut value_order: Vec<(usize, usize)> = index_map
162 .iter()
163 .enumerate()
164 .map(|(old, &new)| (new, old))
165 .collect();
166 value_order.sort_by_key(|(new, _)| *new);
167
168 let mut temp_values: Vec<Option<V>> = input_values.into_iter().map(Some).collect();
170 for (_, old_idx) in value_order {
171 let val: Option<V> = temp_values[old_idx].take();
172 values.push(val.unwrap());
173 }
174
175 IntervalTree {
176 starts,
177 ends,
178 values,
179 nodes,
180 by_end_indices,
181 ends_desc,
182 }
183 }
184}
185
186struct NodeData {
188 pivot_idx: usize,
189 containing: Vec<usize>,
190 left: usize,
191 right: usize,
192}
193
194struct TreePlanner<'a, T> {
196 starts: &'a [T],
197 ends: &'a [T],
198 node_intervals: Vec<NodeData>,
199}
200
201impl<'a, T: Ord + Copy> TreePlanner<'a, T> {
202 fn new(starts: &'a [T], ends: &'a [T]) -> Self {
203 Self {
204 starts,
205 ends,
206 node_intervals: Vec::new(),
207 }
208 }
209
210 fn plan_node(&mut self, indices: &[usize]) -> usize {
211 if indices.is_empty() {
212 return Node::NULL;
213 }
214
215 let pivot_idx = self.find_median_endpoint(indices);
217 let pivot = self.starts[pivot_idx];
218
219 let mut containing = Vec::new();
221 let mut left_indices = Vec::new();
222 let mut right_indices = Vec::new();
223
224 for &idx in indices {
225 let start = self.starts[idx];
226 let end = self.ends[idx];
227
228 if end <= pivot {
229 left_indices.push(idx);
230 } else if start > pivot {
231 right_indices.push(idx);
232 } else {
233 containing.push(idx);
234 }
235 }
236
237 let node_idx = self.node_intervals.len();
239 self.node_intervals.push(NodeData {
240 pivot_idx,
241 containing,
242 left: Node::NULL,
243 right: Node::NULL,
244 });
245
246 let left_child = self.plan_node(&left_indices);
248 let right_child = self.plan_node(&right_indices);
249
250 self.node_intervals[node_idx].left = left_child;
251 self.node_intervals[node_idx].right = right_child;
252
253 node_idx
254 }
255
256 fn find_median_endpoint(&self, indices: &[usize]) -> usize {
257 let mut endpoints: Vec<T> = Vec::with_capacity(indices.len() * 2);
258 for &idx in indices {
259 endpoints.push(self.starts[idx]);
260 endpoints.push(self.ends[idx]);
261 }
262 endpoints.sort();
263
264 let median = endpoints[endpoints.len() / 2];
265
266 for &idx in indices {
267 if self.starts[idx] <= median && median < self.ends[idx] {
268 return idx;
269 }
270 }
271
272 indices[0]
273 }
274}