1use alloc::vec::Vec;
4use core::ops::ControlFlow;
5
6use crate::builder::IntervalTreeBuilder;
7use crate::query::QueryIter;
8use crate::Interval;
9
10#[derive(Debug, Clone)]
22pub struct IntervalTree<T, V> {
23 pub(crate) starts: Vec<T>,
25 pub(crate) ends: Vec<T>,
27 pub(crate) values: Vec<V>,
29 pub(crate) nodes: Vec<Node>,
31 pub(crate) by_end_indices: Vec<usize>,
33 pub(crate) ends_desc: Vec<T>,
35}
36
37#[derive(Debug, Clone)]
39pub(crate) struct Node {
40 pub pivot_idx: usize,
42 pub data_begin: usize,
44 pub data_end: usize,
46 pub by_end_begin: usize,
48 pub by_end_end: usize,
50 pub left: usize,
52 pub right: usize,
54}
55
56impl Node {
57 pub const NULL: usize = usize::MAX;
58
59 #[inline]
60 pub fn has_left(&self) -> bool {
61 self.left != Self::NULL
62 }
63
64 #[inline]
65 pub fn has_right(&self) -> bool {
66 self.right != Self::NULL
67 }
68}
69
70impl<T, V> IntervalTree<T, V> {
71 #[must_use]
73 pub fn builder() -> IntervalTreeBuilder<T, V> {
74 IntervalTreeBuilder::new()
75 }
76
77 #[inline]
79 #[must_use]
80 pub fn len(&self) -> usize {
81 self.values.len()
82 }
83
84 #[inline]
86 #[must_use]
87 pub fn is_empty(&self) -> bool {
88 self.values.is_empty()
89 }
90
91 #[inline]
93 #[must_use]
94 pub fn node_count(&self) -> usize {
95 self.nodes.len()
96 }
97}
98
99impl<T: Ord + Copy, V> IntervalTree<T, V> {
100 #[inline]
104 pub fn query<R: Into<Interval<T>>>(&self, range: R) -> QueryIter<'_, T, V> {
105 QueryIter::new(self, range.into())
106 }
107
108 pub fn query_with<R, F, B>(&self, range: R, mut callback: F) -> ControlFlow<B>
113 where
114 R: Into<Interval<T>>,
115 F: FnMut(&Interval<T>, &V) -> ControlFlow<B>,
116 {
117 let query = range.into();
118 self.query_node(0, &query, &mut callback)
119 }
120
121 fn query_node<F, B>(
122 &self,
123 node_idx: usize,
124 query: &Interval<T>,
125 callback: &mut F,
126 ) -> ControlFlow<B>
127 where
128 F: FnMut(&Interval<T>, &V) -> ControlFlow<B>,
129 {
130 if node_idx >= self.nodes.len() {
131 return ControlFlow::Continue(());
132 }
133
134 let node = &self.nodes[node_idx];
135 let pivot = self.starts[node.pivot_idx];
136
137 if query.start <= pivot && pivot < query.end {
139 for i in node.data_begin..node.data_end {
141 let interval = Interval {
142 start: self.starts[i],
143 end: self.ends[i],
144 };
145 callback(&interval, &self.values[i])?;
146 }
147
148 if node.has_left() {
150 self.query_node(node.left, query, callback)?;
151 }
152 if node.has_right() {
153 self.query_node(node.right, query, callback)?;
154 }
155 }
156 else if pivot < query.start {
158 for pos in node.by_end_begin..node.by_end_end {
160 let i = self.by_end_indices[pos];
161 let end = self.ends[i];
162 if end <= query.start {
163 break; }
165 let interval = Interval {
166 start: self.starts[i],
167 end,
168 };
169 callback(&interval, &self.values[i])?;
170 }
171
172 if node.has_right() {
173 self.query_node(node.right, query, callback)?;
174 }
175 }
176 else {
178 for i in node.data_begin..node.data_end {
181 let start = self.starts[i];
182 if start >= query.end {
183 break; }
185 let interval = Interval {
186 start,
187 end: self.ends[i],
188 };
189 callback(&interval, &self.values[i])?;
190 }
191
192 if node.has_left() {
193 self.query_node(node.left, query, callback)?;
194 }
195 }
196
197 ControlFlow::Continue(())
198 }
199}
200
201impl<V> IntervalTree<i64, V> {
203 pub fn query_simd<R, F, B>(&self, range: R, mut callback: F) -> ControlFlow<B>
205 where
206 R: Into<Interval<i64>>,
207 F: FnMut(&Interval<i64>, &V) -> ControlFlow<B>,
208 {
209 let query = range.into();
210 self.query_node_simd(0, &query, &mut callback)
211 }
212
213 fn query_node_simd<F, B>(
214 &self,
215 node_idx: usize,
216 query: &Interval<i64>,
217 callback: &mut F,
218 ) -> ControlFlow<B>
219 where
220 F: FnMut(&Interval<i64>, &V) -> ControlFlow<B>,
221 {
222 if node_idx >= self.nodes.len() {
223 return ControlFlow::Continue(());
224 }
225
226 let node = &self.nodes[node_idx];
227 let pivot = self.starts[node.pivot_idx];
228
229 if query.start <= pivot && pivot < query.end {
230 for i in node.data_begin..node.data_end {
232 let interval = Interval {
233 start: self.starts[i],
234 end: self.ends[i],
235 };
236 callback(&interval, &self.values[i])?;
237 }
238
239 if node.has_left() {
240 self.query_node_simd(node.left, query, callback)?;
241 }
242 if node.has_right() {
243 self.query_node_simd(node.right, query, callback)?;
244 }
245 } else if pivot < query.start {
246 let node_ends = &self.ends_desc[node.by_end_begin..node.by_end_end];
248 let cutoff = crate::simd::find_le_threshold_i64(node_ends, query.start);
249
250 for pos in node.by_end_begin..(node.by_end_begin + cutoff) {
251 let i = self.by_end_indices[pos];
252 let interval = Interval {
253 start: self.starts[i],
254 end: self.ends[i],
255 };
256 callback(&interval, &self.values[i])?;
257 }
258
259 if node.has_right() {
260 self.query_node_simd(node.right, query, callback)?;
261 }
262 } else {
263 let node_starts = &self.starts[node.data_begin..node.data_end];
265 let cutoff = crate::simd::find_ge_threshold_i64(node_starts, query.end);
266
267 for i in node.data_begin..(node.data_begin + cutoff) {
268 let interval = Interval {
269 start: self.starts[i],
270 end: self.ends[i],
271 };
272 callback(&interval, &self.values[i])?;
273 }
274
275 if node.has_left() {
276 self.query_node_simd(node.left, query, callback)?;
277 }
278 }
279
280 ControlFlow::Continue(())
281 }
282}
283
284unsafe impl<T: Send, V: Send> Send for IntervalTree<T, V> {}
286unsafe impl<T: Sync, V: Sync> Sync for IntervalTree<T, V> {}