im_interval_tree/lib.rs
1/*!
2 * An immutable data structure for storing and querying a collection of intervals
3 *
4 * ```
5 * use std::ops::Bound::*;
6 * use im_interval_tree::{IntervalTree, Interval};
7 *
8 * // Construct a tree of intervals
9 * let tree : IntervalTree<u8> = IntervalTree::new();
10 * let tree = tree.insert(Interval::new(Included(1), Excluded(3)));
11 * let tree = tree.insert(Interval::new(Included(2), Excluded(4)));
12 * let tree = tree.insert(Interval::new(Included(5), Unbounded));
13 * let tree = tree.insert(Interval::new(Excluded(7), Included(8)));
14 *
15 * // Query for overlapping intervals
16 * let query = tree.query_interval(&Interval::new(Included(3), Included(6)));
17 * assert_eq!(
18 * query.collect::<Vec<Interval<u8>>>(),
19 * vec![
20 * Interval::new(Included(2), Excluded(4)),
21 * Interval::new(Included(5), Unbounded)
22 * ]
23 * );
24 *
25 * // Query for a specific point
26 * let query = tree.query_point(&2);
27 * assert_eq!(
28 * query.collect::<Vec<Interval<u8>>>(),
29 * vec![
30 * Interval::new(Included(2), Excluded(4)),
31 * Interval::new(Included(1), Excluded(3))
32 * ]
33 * );
34 * ```
35*/
36#[cfg(test)]
37mod test;
38
39use std::cmp::*;
40use std::ops::Bound;
41use std::ops::Bound::*;
42use std::rc::Rc;
43
44mod interval;
45pub use crate::interval::Interval;
46use crate::interval::*;
47
48#[derive(Clone, Hash)]
49struct Node<T: Ord + Clone> {
50 interval: Interval<T>,
51 left: Option<Rc<Node<T>>>,
52 right: Option<Rc<Node<T>>>,
53 height: usize,
54 max: Rc<Bound<T>>,
55 min: Rc<Bound<T>>,
56}
57
58impl<T: Ord + Clone> Node<T> {
59 fn new(
60 interval: Interval<T>,
61 left: Option<Rc<Node<T>>>,
62 right: Option<Rc<Node<T>>>,
63 ) -> Node<T> {
64 let height = usize::max(Self::height(&left), Self::height(&right)) + 1;
65 let max = Self::get_max(&interval, &left, &right);
66 let min = Self::get_min(&interval, &left, &right);
67 Node {
68 interval: interval,
69 left: left,
70 right: right,
71 height: height,
72 max: max,
73 min: min,
74 }
75 }
76
77 fn leaf(interval: Interval<T>) -> Node<T> {
78 Node::new(interval, None, None)
79 }
80
81 fn height(node: &Option<Rc<Node<T>>>) -> usize {
82 match node {
83 None => 0,
84 Some(n) => n.height,
85 }
86 }
87
88 fn get_max(
89 interval: &Interval<T>,
90 left: &Option<Rc<Node<T>>>,
91 right: &Option<Rc<Node<T>>>,
92 ) -> Rc<Bound<T>> {
93 let mid = &interval.high;
94 match (left, right) {
95 (None, None) => mid.clone(),
96 (None, Some(r)) => high_bound_max(mid, &r.max),
97 (Some(l), None) => high_bound_max(mid, &l.max),
98 (Some(l), Some(r)) => high_bound_max(mid, &high_bound_max(&l.max, &r.max)),
99 }
100 }
101
102 fn get_min(
103 interval: &Interval<T>,
104 left: &Option<Rc<Node<T>>>,
105 right: &Option<Rc<Node<T>>>,
106 ) -> Rc<Bound<T>> {
107 let mid = &interval.low;
108 match (left, right) {
109 (None, None) => mid.clone(),
110 (None, Some(r)) => low_bound_min(mid, &r.min),
111 (Some(l), None) => low_bound_min(mid, &l.min),
112 (Some(l), Some(r)) => low_bound_min(mid, &low_bound_min(&l.min, &r.min)),
113 }
114 }
115
116 fn balance_factor(&self) -> isize {
117 (Self::height(&self.left) as isize) - (Self::height(&self.right) as isize)
118 }
119
120 fn insert(&self, interval: Interval<T>) -> Self {
121 let res = if &interval < &self.interval {
122 let insert_left = match &self.left {
123 None => Node::leaf(interval),
124 Some(left_tree) => left_tree.insert(interval),
125 };
126 Node::new(
127 self.interval.clone(),
128 Some(Rc::new(insert_left)),
129 self.right.clone(),
130 )
131 } else if &interval > &self.interval {
132 let insert_right = match &self.right {
133 None => Node::leaf(interval),
134 Some(right_tree) => right_tree.insert(interval),
135 };
136 Node::new(
137 self.interval.clone(),
138 self.left.clone(),
139 Some(Rc::new(insert_right)),
140 )
141 } else {
142 self.clone()
143 };
144 res.balance()
145 }
146
147 fn get_minimum(&self) -> Interval<T> {
148 match &self.left {
149 None => self.interval.clone(),
150 Some(left_tree) => left_tree.get_minimum(),
151 }
152 }
153
154 fn remove(&self, interval: &Interval<T>) -> Option<Rc<Self>> {
155 let res = if interval == &self.interval {
156 match (&self.left, &self.right) {
157 (None, None) => None,
158 (Some(left_tree), None) => Some(left_tree.clone()),
159 (None, Some(right_tree)) => Some(right_tree.clone()),
160 (Some(_), Some(right_tree)) => {
161 let successor = right_tree.get_minimum();
162 let new_node = Node::new(
163 successor.clone(),
164 self.left.clone(),
165 right_tree.remove(&successor),
166 );
167 Some(Rc::new(new_node))
168 }
169 }
170 } else if interval < &self.interval {
171 match &self.left {
172 None => Some(Rc::new(self.clone())),
173 Some(left_tree) => Some(Rc::new(self.replace_left(left_tree.remove(interval)))),
174 }
175 } else {
176 match &self.right {
177 None => Some(Rc::new(self.clone())),
178 Some(right_tree) => Some(Rc::new(self.replace_right(right_tree.remove(interval)))),
179 }
180 };
181 match res {
182 None => None,
183 Some(r) => Some(Rc::new(r.balance())),
184 }
185 }
186
187 fn replace_left(&self, new_left: Option<Rc<Node<T>>>) -> Node<T> {
188 Self::new(self.interval.clone(), new_left, self.right.clone())
189 }
190
191 fn replace_right(&self, new_right: Option<Rc<Node<T>>>) -> Node<T> {
192 Self::new(self.interval.clone(), self.left.clone(), new_right)
193 }
194
195 fn rotate_right(&self) -> Self {
196 let pivot = self.left.as_ref().unwrap();
197 let new_right = self.replace_left(pivot.right.clone());
198 pivot.replace_right(Some(Rc::new(new_right)))
199 }
200
201 fn rotate_left(&self) -> Self {
202 let pivot = self.right.as_ref().unwrap();
203 let new_left = self.replace_right(pivot.left.clone());
204 pivot.replace_left(Some(Rc::new(new_left)))
205 }
206
207 fn balance(&self) -> Self {
208 let balance_factor = self.balance_factor();
209 if balance_factor < -1 {
210 let right = self.right.as_ref().unwrap();
211 if right.balance_factor() > 0 {
212 self.replace_right(Some(Rc::new(right.rotate_right())))
213 .rotate_left()
214 } else {
215 self.rotate_left()
216 }
217 } else if balance_factor > 1 {
218 let left = self.left.as_ref().unwrap();
219 if left.balance_factor() < 0 {
220 self.replace_left(Some(Rc::new(left.rotate_left())))
221 .rotate_right()
222 } else {
223 self.rotate_right()
224 }
225 } else {
226 self.clone()
227 }
228 }
229}
230
231/// An Iterator over Intervals matching some query
232pub struct Iter<T: Ord + Clone> {
233 stack: Vec<Rc<Node<T>>>,
234 query: Interval<T>,
235}
236
237impl<T: Ord + Clone> Iterator for Iter<T> {
238 type Item = Interval<T>;
239 fn next(&mut self) -> Option<Self::Item> {
240 while let Some(node) = self.stack.pop() {
241 if let Some(left_tree) = &node.left {
242 let max_is_gte = match (&*left_tree.max, self.query.low()) {
243 (Included(max), Included(low)) => max >= low,
244 (Included(max), Excluded(low))
245 | (Excluded(max), Included(low))
246 | (Excluded(max), Excluded(low)) => max > low,
247 _ => true,
248 };
249 if max_is_gte {
250 self.stack.push(left_tree.clone())
251 }
252 }
253 if let Some(right_tree) = &node.right {
254 let min_is_lte = match (&*right_tree.min, self.query.high()) {
255 (Included(min), Included(high)) => min <= high,
256 (Included(min), Excluded(high))
257 | (Excluded(min), Included(high))
258 | (Excluded(min), Excluded(high)) => min < high,
259 _ => true,
260 };
261 if min_is_lte {
262 self.stack.push(right_tree.clone())
263 }
264 }
265 if self.query.overlaps(&node.interval) {
266 return Some(node.interval.clone());
267 }
268 }
269 None
270 }
271}
272
273/// An immutable data structure for storing and querying a collection of intervals
274///
275/// # Example
276/// ```
277/// use std::ops::Bound::*;
278/// use im_interval_tree::{IntervalTree, Interval};
279///
280/// // Construct a tree of intervals
281/// let tree : IntervalTree<u8> = IntervalTree::new();
282/// let tree = tree.insert(Interval::new(Included(1), Excluded(3)));
283/// let tree = tree.insert(Interval::new(Included(2), Excluded(4)));
284/// let tree = tree.insert(Interval::new(Included(5), Unbounded));
285/// let tree = tree.insert(Interval::new(Excluded(7), Included(8)));
286///
287/// // Query for overlapping intervals
288/// let query = tree.query_interval(&Interval::new(Included(3), Included(6)));
289/// assert_eq!(
290/// query.collect::<Vec<Interval<u8>>>(),
291/// vec![
292/// Interval::new(Included(2), Excluded(4)),
293/// Interval::new(Included(5), Unbounded)
294/// ]
295/// );
296///
297/// // Query for a specific point
298/// let query = tree.query_point(&2);
299/// assert_eq!(
300/// query.collect::<Vec<Interval<u8>>>(),
301/// vec![
302/// Interval::new(Included(2), Excluded(4)),
303/// Interval::new(Included(1), Excluded(3))
304/// ]
305/// );
306/// ```
307#[derive(Clone, Hash)]
308pub struct IntervalTree<T: Ord + Clone> {
309 root: Option<Rc<Node<T>>>,
310}
311
312impl<T: Ord + Clone> IntervalTree<T> {
313 /// Construct an empty IntervalTree
314 pub fn new() -> IntervalTree<T> {
315 IntervalTree { root: None }
316 }
317
318 /// Construct a new IntervalTree with the given Interval added
319 ///
320 /// # Example
321 /// ```
322 /// # use std::ops::Bound::*;
323 /// # use im_interval_tree::{IntervalTree, Interval};
324 /// let tree : IntervalTree<u8> = IntervalTree::new();
325 /// let tree = tree.insert(Interval::new(Included(1), Included(2)));
326 /// assert_eq!(
327 /// tree.iter().collect::<Vec<Interval<u8>>>(),
328 /// vec![Interval::new(Included(1), Included(2))]
329 /// );
330 /// ```
331 pub fn insert(&self, interval: Interval<T>) -> IntervalTree<T> {
332 let new_root = match &self.root {
333 None => Node::leaf(interval),
334 Some(node) => node.insert(interval),
335 };
336 IntervalTree {
337 root: Some(Rc::new(new_root)),
338 }
339 }
340
341 /// Construct a new IntervalTree minus the given Interval, if present
342 ///
343 /// # Example
344 /// ```
345 /// # use std::ops::Bound::*;
346 /// # use im_interval_tree::{IntervalTree, Interval};
347 /// let tree : IntervalTree<u8> = IntervalTree::new();
348 /// let tree = tree.insert(Interval::new(Included(1), Included(2)));
349 /// let tree = tree.insert(Interval::new(Included(1), Included(3)));
350 ///
351 /// let tree = tree.remove(&Interval::new(Included(1), Included(2)));
352 /// assert_eq!(
353 /// tree.iter().collect::<Vec<Interval<u8>>>(),
354 /// vec![Interval::new(Included(1), Included(3))]
355 /// );
356 /// ```
357 pub fn remove(&self, interval: &Interval<T>) -> IntervalTree<T> {
358 match &self.root {
359 None => IntervalTree::new(),
360 Some(node) => IntervalTree {
361 root: node.remove(interval),
362 },
363 }
364 }
365
366 /// Return an Iterator over all the intervals in the tree that overlap
367 /// with the given interval
368 ///
369 /// # Example
370 /// ```
371 /// # use std::ops::Bound::*;
372 /// # use im_interval_tree::{IntervalTree, Interval};
373 /// let tree : IntervalTree<u8> = IntervalTree::new();
374 /// let tree = tree.insert(Interval::new(Included(1), Excluded(3)));
375 /// let tree = tree.insert(Interval::new(Included(5), Unbounded));
376 ///
377 /// let query = tree.query_interval(&Interval::new(Included(3), Included(6)));
378 /// assert_eq!(
379 /// query.collect::<Vec<Interval<u8>>>(),
380 /// vec![Interval::new(Included(5), Unbounded)]
381 /// );
382 /// ```
383 pub fn query_interval(&self, interval: &Interval<T>) -> impl Iterator<Item = Interval<T>> + '_ {
384 let mut stack = Vec::new();
385 if let Some(node) = &self.root {
386 stack.push(node.clone())
387 }
388 Iter {
389 stack: stack,
390 query: interval.clone(),
391 }
392 }
393
394 /// Return an Iterator over all the intervals in the tree that contain
395 /// the given point
396 ///
397 /// This is equivalent to `tree.query_interval(Interval::new(Included(point), Included(point)))`
398 ///
399 /// # Example
400 /// ```
401 /// # use std::ops::Bound::*;
402 /// # use im_interval_tree::{IntervalTree, Interval};
403 /// let tree : IntervalTree<u8> = IntervalTree::new();
404 /// let tree = tree.insert(Interval::new(Included(1), Excluded(3)));
405 /// let tree = tree.insert(Interval::new(Included(5), Unbounded));
406 ///
407 /// let query = tree.query_point(&2);
408 /// assert_eq!(
409 /// query.collect::<Vec<Interval<u8>>>(),
410 /// vec![Interval::new(Included(1), Excluded(3))]
411 /// );
412 /// ```
413 pub fn query_point(&self, point: &T) -> impl Iterator<Item = Interval<T>> + '_ {
414 let interval = Interval::new(Included(point.clone()), Included(point.clone()));
415 self.query_interval(&interval)
416 }
417
418 /// Return an Iterator over all the intervals in the tree
419 ///
420 /// This is equivalent to `tree.query_interval(Unbounded, Unbounded)`
421 ///
422 /// # Example
423 /// ```
424 /// # use std::ops::Bound::*;
425 /// # use im_interval_tree::{IntervalTree, Interval};
426 /// let tree : IntervalTree<u8> = IntervalTree::new();
427 /// let tree = tree.insert(Interval::new(Included(2), Excluded(4)));
428 /// let tree = tree.insert(Interval::new(Included(5), Unbounded));
429 ///
430 /// let iter = tree.iter();
431 /// assert_eq!(
432 /// iter.collect::<Vec<Interval<u8>>>(),
433 /// vec![
434 /// Interval::new(Included(2), Excluded(4)),
435 /// Interval::new(Included(5), Unbounded),
436 /// ]
437 /// );
438 /// ```
439 pub fn iter(&self) -> impl Iterator<Item = Interval<T>> + '_ {
440 self.query_interval(&Interval::new(Unbounded, Unbounded))
441 }
442}