1use std::{
2 collections::BTreeMap,
3 fmt::{self, Debug},
4 ops::Range,
5};
6
7#[derive(Clone, PartialEq, Eq)]
9pub struct DisjointIntervals<T> {
10 intervals: BTreeMap<T, T>,
12}
13
14#[derive(Debug, Clone, PartialEq, Eq)]
16pub enum InsertItem<T> {
17 New(Range<T>),
19 Overlap(Range<T>),
21}
22
23#[derive(Debug, Clone, PartialEq, Eq)]
25pub enum RemoveItem<T> {
26 Remove(Range<T>),
28 Absent(Range<T>),
30}
31
32impl<T> DisjointIntervals<T>
33where
34 T: Ord + Clone + Copy,
35{
36 pub fn new() -> Self {
37 Self {
38 intervals: BTreeMap::new(),
39 }
40 }
41
42 pub fn len(&self) -> usize {
43 self.intervals.len()
44 }
45
46 pub fn is_empty(&self) -> bool {
47 self.intervals.is_empty()
48 }
49
50 pub fn iter(&self) -> impl Iterator<Item = Range<T>> {
51 self.intervals.iter().map(|(&start, &end)| start..end)
52 }
53
54 pub fn insert<U, F>(&mut self, interval: Range<T>, init: U, f: F) -> U
77 where
78 F: FnMut(U, InsertItem<T>) -> U,
79 {
80 assert!(!interval.is_empty());
81
82 let mut acc = init;
83 let mut f = f;
84 let (insert_start, mut start, insert_end) =
85 match self.intervals.range(..=interval.start).last() {
86 Some((&prev_start, &prev_end)) if interval.start <= prev_end => {
87 if interval.start < prev_end {
88 let overlap_end = prev_end.min(interval.end);
89 acc = f(acc, InsertItem::Overlap(interval.start..overlap_end));
90 }
91 self.intervals.remove(&prev_start);
92 (
93 prev_start,
94 prev_end.max(interval.start),
95 interval.end.max(prev_end),
96 )
97 }
98 _ => (interval.start, interval.start, interval.end),
99 };
100
101 while let Some((&next_start, &next_end)) = self.intervals.range(start..=insert_end).next() {
103 assert!(start < next_start);
104 assert!(next_start <= insert_end);
105
106 acc = f(acc, InsertItem::New(start..next_start));
107
108 self.intervals.remove(&next_start);
109
110 if insert_end <= next_end {
111 acc = f(acc, InsertItem::Overlap(next_start..insert_end));
113 self.intervals
114 .insert(insert_start, insert_end.max(next_end));
115 return acc;
116 }
117
118 acc = f(acc, InsertItem::Overlap(next_start..next_end));
120 start = next_end;
121 }
122
123 if start < insert_end {
124 acc = f(acc, InsertItem::New(start..insert_end));
125 }
126 self.intervals.insert(insert_start, insert_end);
127 acc
128 }
129
130 pub fn remove<U, F>(&mut self, interval: Range<T>, init: U, f: F) -> U
153 where
154 F: FnMut(U, RemoveItem<T>) -> U,
155 {
156 assert!(!interval.is_empty());
157
158 let mut acc = init;
159 let mut f = f;
160 let remove_end = interval.end;
161 let mut start = match self.intervals.range(..=interval.start).last() {
162 Some((&prev_start, &prev_end)) if interval.start < prev_end => {
163 self.intervals.remove(&prev_start);
164
165 if prev_start < interval.start {
166 self.intervals.insert(prev_start, interval.start);
167 }
168
169 let overlap_end = prev_end.min(remove_end);
170 acc = f(acc, RemoveItem::Remove(interval.start..overlap_end));
171
172 if prev_end > remove_end {
173 self.intervals.insert(remove_end, prev_end);
174 return acc;
175 }
176 overlap_end
177 }
178 _ => interval.start,
179 };
180
181 while let Some((&next_start, &next_end)) = self.intervals.range(start..remove_end).next() {
183 assert!(start <= next_start);
184 assert!(next_start < remove_end);
185
186 if start < next_start {
187 acc = f(acc, RemoveItem::Absent(start..next_start));
188 }
189
190 self.intervals.remove(&next_start);
191
192 if next_end <= remove_end {
193 acc = f(acc, RemoveItem::Remove(next_start..next_end));
195 start = next_end;
196 } else {
197 acc = f(acc, RemoveItem::Remove(next_start..remove_end));
199 self.intervals.insert(remove_end, next_end);
200 return acc;
201 }
202 }
203
204 if start < remove_end {
205 acc = f(acc, RemoveItem::Absent(start..remove_end));
206 }
207
208 acc
209 }
210
211 pub fn ge(&self, x: T) -> Option<Range<T>> {
227 self.intervals
228 .range(x..)
229 .next()
230 .map(|(&start, &end)| start..end)
231 }
232
233 pub fn le(&self, x: T) -> Option<Range<T>> {
250 self.intervals
251 .range(..=x)
252 .last()
253 .map(|(&start, &end)| start..end)
254 }
255}
256
257impl<T> Debug for DisjointIntervals<T>
258where
259 T: Debug,
260{
261 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
262 f.debug_list().entries(self.intervals.iter()).finish()
263 }
264}
265
266impl<T> Default for DisjointIntervals<T>
267where
268 T: Ord + Clone + Copy,
269{
270 fn default() -> Self {
271 Self::new()
272 }
273}
274
275#[cfg(test)]
276mod tests {
277 use crate::{DisjointIntervals, InsertItem, RemoveItem};
278
279 #[test]
280 fn test_insert_disjoint() {
281 let mut intervals = DisjointIntervals::<i32>::new();
282 intervals.insert(-10..5, (), |_, _| ());
283 intervals.insert(10..15, (), |_, _| ());
284
285 let mut it = intervals.iter();
286 assert_eq!(it.next(), Some(-10..5));
287 assert_eq!(it.next(), Some(10..15));
288 assert_eq!(it.next(), None);
289 }
290
291 #[test]
292 fn test_insert_subset() {
293 let mut intervals = DisjointIntervals::<i32>::new();
294 intervals.insert(-10..5, (), |_, _| ());
295 intervals.insert(-5..0, (), |_, _| ());
296
297 let mut it = intervals.iter();
298 assert_eq!(it.next(), Some(-10..5));
299 assert_eq!(it.next(), None);
300 }
301
302 #[test]
303 fn test_insert_superset() {
304 let mut intervals = DisjointIntervals::<i32>::new();
305 intervals.insert(-5..0, (), |_, _| ());
306 intervals.insert(-10..5, (), |_, _| ());
307
308 let mut it = intervals.iter();
309 assert_eq!(it.next(), Some(-10..5));
310 assert_eq!(it.next(), None);
311 }
312
313 #[test]
314 fn test_insert_intersect() {
315 let mut intervals = DisjointIntervals::<i32>::new();
316 intervals.insert(-10..5, (), |_, _| ());
317 intervals.insert(0..10, (), |_, _| ());
318
319 let mut it = intervals.iter();
320 assert_eq!(it.next(), Some(-10..10));
321 assert_eq!(it.next(), None);
322 }
323
324 #[test]
325 fn test_insert_intersect_3() {
326 let mut intervals = DisjointIntervals::<i32>::new();
327 intervals.insert(-10..5, (), |_, _| ());
328 intervals.insert(10..20, (), |_, _| ());
329 intervals.insert(0..12, (), |_, _| ());
330
331 let mut it = intervals.iter();
332 assert_eq!(it.next(), Some(-10..20));
333 assert_eq!(it.next(), None);
334 }
335
336 #[test]
337 fn test_insert_touch_left_right() {
338 let mut intervals = DisjointIntervals::<i32>::new();
339 intervals.insert(-10..5, (), |_, _| ());
340 intervals.insert(5..10, (), |_, _| ());
341
342 let mut it = intervals.iter();
343 assert_eq!(it.next(), Some(-10..10));
344 assert_eq!(it.next(), None);
345 }
346
347 #[test]
348 fn test_insert_touch_right_left() {
349 let mut intervals = DisjointIntervals::<i32>::new();
350 intervals.insert(5..10, (), |_, _| ());
351 intervals.insert(-10..5, (), |_, _| ());
352
353 let mut it = intervals.iter();
354 assert_eq!(it.next(), Some(-10..10));
355 assert_eq!(it.next(), None);
356 }
357
358 #[test]
359 fn test_insert_touch_3() {
360 let mut intervals = DisjointIntervals::<i32>::new();
361 intervals.insert(-10..5, (), |_, _| ());
362 intervals.insert(10..20, (), |_, _| ());
363 intervals.insert(5..10, (), |_, _| ());
364
365 let mut it = intervals.iter();
366 assert_eq!(it.next(), Some(-10..20));
367 assert_eq!(it.next(), None);
368 }
369
370 #[test]
371 fn test_insert_fold_1() {
372 let mut intervals = DisjointIntervals::<i32>::new();
373
374 let insert_items = intervals.insert(-10..5, Vec::new(), |mut acc, item| {
375 acc.push(item);
376 acc
377 });
378 assert_eq!(insert_items, vec![InsertItem::New(-10..5)]);
379 }
380
381 #[test]
382 fn test_insert_fold() {
383 let mut intervals = DisjointIntervals::<i32>::new();
384 intervals.insert(-10..-5, (), |_, _| ());
385 intervals.insert(0..5, (), |_, _| ());
386 intervals.insert(10..15, (), |_, _| ());
387
388 let insert_items = intervals.insert(-7..12, Vec::new(), |mut acc, item| {
389 acc.push(item);
390 acc
391 });
392 assert_eq!(
393 insert_items,
394 vec![
395 InsertItem::Overlap(-7..-5),
396 InsertItem::New(-5..0),
397 InsertItem::Overlap(0..5),
398 InsertItem::New(5..10),
399 InsertItem::Overlap(10..12)
400 ],
401 );
402 }
403
404 #[test]
405 fn test_remove_subset() {
406 let mut intervals = DisjointIntervals::<i32>::new();
407 intervals.insert(-10..5, (), |_, _| ());
408 intervals.remove(-5..0, (), |_, _| ());
409
410 let mut it = intervals.iter();
411 assert_eq!(it.next(), Some(-10..-5));
412 assert_eq!(it.next(), Some(0..5));
413 assert_eq!(it.next(), None);
414 }
415
416 #[test]
417 fn test_remove_superset() {
418 let mut intervals = DisjointIntervals::<i32>::new();
419 intervals.insert(-5..0, (), |_, _| ());
420 intervals.remove(-10..5, (), |_, _| ());
421
422 let mut it = intervals.iter();
423 assert_eq!(it.next(), None);
424 }
425
426 #[test]
427 fn test_remove_intersect() {
428 let mut intervals = DisjointIntervals::<i32>::new();
429 intervals.insert(-10..5, (), |_, _| ());
430 intervals.remove(0..10, (), |_, _| ());
431
432 let mut it = intervals.iter();
433 assert_eq!(it.next(), Some(-10..0));
434 assert_eq!(it.next(), None);
435 }
436
437 #[test]
438 fn test_remove_touch_left() {
439 let mut intervals = DisjointIntervals::<i32>::new();
440 intervals.insert(-10..5, (), |_, _| ());
441 intervals.remove(-10..0, (), |_, _| ());
442
443 let mut it = intervals.iter();
444 assert_eq!(it.next(), Some(0..5));
445 assert_eq!(it.next(), None);
446 }
447
448 #[test]
449 fn test_remove_touch_right() {
450 let mut intervals = DisjointIntervals::<i32>::new();
451 intervals.insert(5..10, (), |_, _| ());
452 intervals.remove(8..10, (), |_, _| ());
453
454 let mut it = intervals.iter();
455 assert_eq!(it.next(), Some(5..8));
456 assert_eq!(it.next(), None);
457 }
458
459 #[test]
460 fn test_remove_exact() {
461 let mut intervals = DisjointIntervals::<i32>::new();
462 intervals.insert(-10..5, (), |_, _| ());
463 intervals.remove(-10..5, (), |_, _| ());
464
465 let mut it = intervals.iter();
466 assert_eq!(it.next(), None);
467 }
468
469 #[test]
470 fn test_remove_fold_empty() {
471 let mut intervals = DisjointIntervals::<i32>::new();
472
473 let remove_items = intervals.remove(-10..5, Vec::new(), |mut acc, item| {
474 acc.push(item);
475 acc
476 });
477
478 assert_eq!(remove_items, vec![RemoveItem::Absent(-10..5)]);
479 }
480
481 #[test]
482 fn test_remove_fold() {
483 use crate::RemoveItem;
484
485 let mut intervals = DisjointIntervals::<i32>::new();
486 intervals.insert(-10..-5, (), |_, _| ());
487 intervals.insert(0..5, (), |_, _| ());
488 intervals.insert(10..15, (), |_, _| ());
489
490 let remove_items = intervals.remove(-7..12, Vec::new(), |mut acc, item| {
491 acc.push(item);
492 acc
493 });
494 assert_eq!(
495 remove_items,
496 vec![
497 RemoveItem::Remove(-7..-5),
498 RemoveItem::Absent(-5..0),
499 RemoveItem::Remove(0..5),
500 RemoveItem::Absent(5..10),
501 RemoveItem::Remove(10..12)
502 ],
503 );
504
505 let mut it = intervals.iter();
506 assert_eq!(it.next(), Some(-10..-7));
507 assert_eq!(it.next(), Some(12..15));
508 assert_eq!(it.next(), None);
509 }
510}