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}