1#![cfg_attr(not(feature = "std"), no_std)]
38#![deny(clippy::all)]
39#![warn(clippy::pedantic, clippy::nursery)]
40#![allow(clippy::module_name_repetitions)]
41
42extern crate alloc;
43
44#[cfg(feature = "jemalloc")]
45#[global_allocator]
46static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
47
48mod builder;
49mod mutable;
50mod query;
51mod simd;
52mod tree;
53
54pub use builder::IntervalTreeBuilder;
55pub use mutable::{IntervalId, IntervalSet};
56pub use query::{QueryEntry, QueryIter};
57pub use tree::IntervalTree;
58
59#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
61pub struct Interval<T> {
62 pub start: T,
64 pub end: T,
66}
67
68impl<T: Ord> Interval<T> {
69 #[must_use]
75 pub fn new(start: T, end: T) -> Self {
76 assert!(start <= end, "interval start must be <= end");
77 Self { start, end }
78 }
79
80 #[inline]
84 #[must_use]
85 pub fn overlaps(&self, other: &Self) -> bool {
86 self.start < other.end && other.start < self.end
87 }
88
89 #[inline]
91 #[must_use]
92 pub fn contains_point(&self, point: &T) -> bool {
93 self.start <= *point && *point < self.end
94 }
95}
96
97impl<T: Ord> From<core::ops::Range<T>> for Interval<T> {
98 fn from(range: core::ops::Range<T>) -> Self {
99 Self::new(range.start, range.end)
100 }
101}
102
103#[cfg(test)]
104mod tests {
105 use super::*;
106
107 #[test]
108 fn interval_overlap() {
109 let a = Interval::new(0, 10);
110 let b = Interval::new(5, 15);
111 let c = Interval::new(10, 20);
112 let d = Interval::new(20, 30);
113
114 assert!(a.overlaps(&b));
115 assert!(b.overlaps(&a));
116 assert!(!a.overlaps(&c)); assert!(!a.overlaps(&d));
118 }
119
120 #[test]
121 fn interval_contains_point() {
122 let a = Interval::new(0, 10);
123 assert!(a.contains_point(&0));
124 assert!(a.contains_point(&5));
125 assert!(!a.contains_point(&10)); assert!(!a.contains_point(&-1));
127 }
128
129 #[test]
130 fn interval_from_range() {
131 let interval: Interval<i32> = (0..10).into();
132 assert_eq!(interval.start, 0);
133 assert_eq!(interval.end, 10);
134 }
135}