Skip to main content

rust_lapper/
lib.rs

1//! This module provides a simple data structure for fast interval searches.
2//! ## Features
3//! - Extremely fast overlap queries on both ordinary genomic datasets and
4//!   datasets with long intervals that engulf many shorter intervals.
5//! - Extremely fast in order queries through the cursor-based `seek()` method.
6//! - Extremely fast intersection counts based on the
7//!   [BITS](https://arxiv.org/pdf/1208.3407.pdf) algorithm
8//! - NEON acceleration on AArch64, runtime-detected AVX2 on x86-64, and an exact
9//!   scalar fallback everywhere else.
10//! - Parallel friendly. Queries are on an immutable structure, even for `seek()`.
11//! - Consumer / Adapter paradigm. Iterators are returned and serve as the main
12//!   API for interacting with the Lapper.
13//!
14//! ## Details:
15//!
16//! ```text
17//!          0  1  2  3  4  5  6  7  8  9  10 11
18//! [0, 10)  X  X  X  X  X  X  X  X  X  X
19//! [2, 5)         X  X  X
20//! [3, 8)            X  X  X  X  X
21//! [3, 8)            X  X  X  X  X
22//! [3, 8)            X  X  X  X  X
23//! [3, 8)            X  X  X  X  X
24//! [5, 9)                  X  X  X  X
25//! [8, 11)                          X  X  X
26//!
27//! Query:  [8, 11)
28//! Answer: [0, 10), [5, 9), [8, 11)
29//! ```
30//!
31//! Most interaction with this crate will be through the [`Lapper`] struct. The
32//! main methods are [`Lapper::find`], [`Lapper::seek`], and [`Lapper::count`].
33//! `find()` handles independent queries, `seek()` reuses a caller-owned cursor
34//! when query starts arrive in order, and `count()` is used when only the number
35//! of overlaps is needed.
36//!
37//! Ranges are half-open: `[start, stop)`. Two ranges overlap when
38//! `interval.start < query.stop` and `interval.stop > query.start`, so adjacent
39//! ranges such as `[0, 10)` and `[10, 20)` do not overlap. This matches the
40//! usual zero-based genomic coordinate system. Signed and unsigned primitive
41//! coordinates are supported.
42//!
43//! Lapper does not use an interval tree. It keeps intervals sorted by start and
44//! builds a small index over fixed blocks of 32 intervals. A prefix maximum
45//! finds the first block that could overlap; each block's minimum and maximum
46//! end positions then prove whether the block is a miss or a dense prefix, and
47//! a next-greater link skips runs of blocks that cannot overlap. Mixed blocks
48//! produce an exact 32-bit overlap mask with NEON, AVX2, or the scalar fallback.
49//! Mask bits are drained from low to high, so results remain borrowed and in
50//! ascending start order.
51//!
52//! The same block algorithm handles ordinary data and the old worst case where
53//! one long interval engulfs many shorter intervals. There is no workload mode
54//! to configure. `merge_overlaps()` remains useful when callers want merged
55//! coverage, while `count()` remains the independent BITS implementation and is
56//! fast regardless of interval shape.
57//!
58//! # Examples
59//!
60//! ```rust
61//!    use rust_lapper::{Interval, Lapper};
62//!    use std::cmp;
63//!    type Iv = Interval<usize, u32>;
64//!
65//!    // create some fake data
66//!    let data: Vec<Iv> = (0..20).step_by(5).map(|x| Iv{start: x, stop: x + 2, val: 0}).collect();
67//!    println!("{:#?}", data);
68//!
69//!    // make lapper structure
70//!    let laps = Lapper::new(data);
71//!
72//!    assert_eq!(laps.find(6, 11).next(), Some(&Iv{start: 5, stop: 7, val: 0}));
73//!
74//!    // Demonstration of seek function. By passing in the &mut cursor, seek can have thread local
75//!    // cursors going
76//!    let mut sim: usize = 0;
77//!    let mut cursor = 0;
78//!    // Calculate the overlap between the query and the found intervals, sum total overlap
79//!    for i in (0..10).step_by(3) {
80//!        sim += laps
81//!            .seek(i, i + 2, &mut cursor)
82//!            .map(|iv| cmp::min(i + 2, iv.stop) - cmp::max(i, iv.start))
83//!            .sum::<usize>();
84//!    }
85//!    assert_eq!(sim, 4);
86//! ```
87use num_traits::{
88    identities::{one, zero},
89    PrimInt,
90};
91use std::cmp::Ordering::{self};
92use std::collections::VecDeque;
93
94mod simd;
95
96use simd::{detect_backend, overlap_mask, MaskBackend, BLOCK_SIZE as INDEX_BLOCK_SIZE};
97
98#[cfg(feature = "with_serde")]
99use serde::{ser::SerializeStruct, Deserialize, Deserializer, Serialize, Serializer};
100
101/// Represent a range from [start, stop)
102/// Inclusive start, exclusive of stop
103#[cfg_attr(feature = "with_serde", derive(Serialize, Deserialize))]
104#[derive(Eq, Debug, Clone)]
105pub struct Interval<I, T>
106where
107    I: PrimInt + Ord + Clone + Send + Sync,
108    T: Eq + Clone + Send + Sync,
109{
110    pub start: I,
111    pub stop: I,
112    pub val: T,
113}
114
115/// Primary interval collection and query index.
116///
117/// The public interval vector is the canonical storage and can be read or used
118/// to mutate payload values. Coordinate or structural changes must use
119/// [`Lapper::insert`] or [`Lapper::merge_overlaps`] so the private query index
120/// is rebuilt.
121#[derive(Debug, Clone)]
122pub struct Lapper<I, T>
123where
124    I: PrimInt + Ord + Clone + Send + Sync,
125    T: Eq + Clone + Send + Sync,
126{
127    /// Intervals in ascending start order.
128    ///
129    /// Directly changing coordinates or vector length leaves the private query
130    /// index stale. Payload-only changes are safe.
131    pub intervals: Vec<Interval<I, T>>,
132    /// Sorted list of start positions,
133    starts: Vec<I>,
134    /// Sorted list of end positions,
135    stops: Vec<I>,
136    /// End positions in the same order as `intervals`, for block-mask queries.
137    stops_by_start: Vec<I>,
138    /// Index of the next block with a strictly larger maximum end, or the
139    /// number of blocks when no such block exists.
140    block_index: Vec<usize>,
141    /// Maximum end position in each fixed-size block.
142    block_max_ends: Vec<I>,
143    /// Minimum end position in each fixed-size block.
144    block_min_ends: Vec<I>,
145    /// Inclusive prefix maximum of `block_max_ends`, used to find the first
146    /// candidate block for a query.
147    block_prefix_max_ends: Vec<I>,
148    /// The length of the longest interval
149    max_len: I,
150    /// Whether a valid interval length exceeds the positive range of `I`.
151    max_len_overflowed: bool,
152    /// The calculated number of positions covered by the intervals
153    cov: Option<I>,
154    /// Whether or not overlaps have been merged
155    pub overlaps_merged: bool,
156}
157
158#[cfg(feature = "with_serde")]
159impl<I, T> Serialize for Lapper<I, T>
160where
161    I: PrimInt + Ord + Clone + Send + Sync + Serialize,
162    T: Eq + Clone + Send + Sync + Serialize,
163{
164    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
165    where
166        S: Serializer,
167    {
168        let mut state = serializer.serialize_struct("Lapper", 6)?;
169        state.serialize_field("intervals", &self.intervals)?;
170        state.serialize_field("starts", &self.starts)?;
171        state.serialize_field("stops", &self.stops)?;
172        state.serialize_field("max_len", &self.max_len)?;
173        state.serialize_field("cov", &self.cov)?;
174        state.serialize_field("overlaps_merged", &self.overlaps_merged)?;
175        state.end()
176    }
177}
178
179#[cfg(feature = "with_serde")]
180#[derive(Deserialize)]
181#[allow(dead_code)]
182struct SerializedLapper<I, T>
183where
184    I: PrimInt + Ord + Clone + Send + Sync,
185    T: Eq + Clone + Send + Sync,
186{
187    intervals: Vec<Interval<I, T>>,
188    starts: Vec<I>,
189    stops: Vec<I>,
190    max_len: I,
191    cov: Option<I>,
192    overlaps_merged: bool,
193}
194
195#[cfg(feature = "with_serde")]
196impl<'de, I, T> Deserialize<'de> for Lapper<I, T>
197where
198    I: PrimInt + Ord + Clone + Send + Sync + Deserialize<'de> + 'static,
199    T: Eq + Clone + Send + Sync + Deserialize<'de>,
200{
201    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
202    where
203        D: Deserializer<'de>,
204    {
205        let serialized = SerializedLapper::<I, T>::deserialize(deserializer)?;
206        let mut lapper = Self::new(serialized.intervals);
207        lapper.cov = serialized.cov;
208        lapper.overlaps_merged = serialized.overlaps_merged;
209        Ok(lapper)
210    }
211}
212
213impl<I, T> Interval<I, T>
214where
215    I: PrimInt + Ord + Clone + Send + Sync,
216    T: Eq + Clone + Send + Sync,
217{
218    /// Compute the intsect between two intervals
219    #[inline]
220    pub fn intersect(&self, other: &Interval<I, T>) -> I {
221        std::cmp::min(self.stop, other.stop)
222            .checked_sub(std::cmp::max(&self.start, &other.start))
223            .unwrap_or_else(zero::<I>)
224    }
225
226    /// Check if two intervals overlap
227    #[inline]
228    pub fn overlap(&self, start: I, stop: I) -> bool {
229        self.start < stop && self.stop > start
230    }
231}
232
233impl<I, T> Ord for Interval<I, T>
234where
235    I: PrimInt + Ord + Clone + Send + Sync,
236    T: Eq + Clone + Send + Sync,
237{
238    #[inline]
239    fn cmp(&self, other: &Interval<I, T>) -> Ordering {
240        match self.start.cmp(&other.start) {
241            Ordering::Less => Ordering::Less,
242            Ordering::Greater => Ordering::Greater,
243            Ordering::Equal => self.stop.cmp(&other.stop),
244        }
245    }
246}
247
248impl<I, T> PartialOrd for Interval<I, T>
249where
250    I: PrimInt + Ord + Clone + Send + Sync,
251    T: Eq + Clone + Send + Sync,
252{
253    #[inline]
254    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
255        Some(self.cmp(other))
256    }
257}
258
259impl<I, T> PartialEq for Interval<I, T>
260where
261    I: PrimInt + Ord + Clone + Send + Sync,
262    T: Eq + Clone + Send + Sync,
263{
264    #[inline]
265    fn eq(&self, other: &Interval<I, T>) -> bool {
266        self.start == other.start && self.stop == other.stop
267    }
268}
269
270impl<I, T> Lapper<I, T>
271where
272    I: PrimInt + Ord + Clone + Send + Sync + 'static,
273    T: Eq + Clone + Send + Sync,
274{
275    /// Create a new instance of Lapper by passing in a vector of Intervals. This vector will
276    /// immediately be sorted by start order.
277    /// ```
278    /// use rust_lapper::{Lapper, Interval};
279    /// let data = (0..20).step_by(5)
280    ///                   .map(|x| Interval{start: x, stop: x + 10, val: true})
281    ///                   .collect::<Vec<Interval<usize, bool>>>();
282    /// let lapper = Lapper::new(data);
283    /// ```
284    pub fn new(mut intervals: Vec<Interval<I, T>>) -> Self {
285        #[cfg(feature = "sort_unstable")]
286        intervals.sort_unstable();
287
288        #[cfg(not(feature = "sort_unstable"))]
289        intervals.sort();
290
291        let mut lapper = Lapper {
292            intervals,
293            starts: Vec::new(),
294            stops: Vec::new(),
295            stops_by_start: Vec::new(),
296            block_index: Vec::new(),
297            block_max_ends: Vec::new(),
298            block_min_ends: Vec::new(),
299            block_prefix_max_ends: Vec::new(),
300            max_len: zero::<I>(),
301            max_len_overflowed: false,
302            cov: None,
303            overlaps_merged: false,
304        };
305        lapper.rebuild_derived();
306        lapper
307    }
308
309    fn rebuild_derived(&mut self) {
310        let (starts, stops_by_start): (Vec<_>, Vec<_>) = self
311            .intervals
312            .iter()
313            .map(|interval| (interval.start, interval.stop))
314            .unzip();
315        self.starts = starts;
316        self.stops = stops_by_start.clone();
317        self.stops_by_start = stops_by_start;
318
319        self.max_len = zero::<I>();
320        self.max_len_overflowed = false;
321        for interval in &self.intervals {
322            match interval.stop.checked_sub(&interval.start) {
323                Some(length) => self.max_len = std::cmp::max(self.max_len, length),
324                None if interval.stop >= interval.start => self.max_len_overflowed = true,
325                None => {}
326            }
327        }
328
329        #[cfg(feature = "sort_unstable")]
330        self.stops.sort_unstable();
331
332        #[cfg(not(feature = "sort_unstable"))]
333        self.stops.sort();
334
335        self.block_max_ends.clear();
336        self.block_min_ends.clear();
337        let interval_count = self.intervals.len();
338        let block_count =
339            interval_count / INDEX_BLOCK_SIZE + usize::from(interval_count % INDEX_BLOCK_SIZE != 0);
340        self.block_max_ends.reserve(block_count);
341        self.block_min_ends.reserve(block_count);
342        for block in self.intervals.chunks(INDEX_BLOCK_SIZE) {
343            let mut max_end = block[0].stop;
344            let mut min_end = max_end;
345            for interval in &block[1..] {
346                max_end = std::cmp::max(max_end, interval.stop);
347                min_end = std::cmp::min(min_end, interval.stop);
348            }
349            self.block_max_ends.push(max_end);
350            self.block_min_ends.push(min_end);
351        }
352
353        self.block_index.clear();
354        self.block_index.resize(block_count, block_count);
355        let mut stack = Vec::<usize>::new();
356        for block in (0..block_count).rev() {
357            while stack.last().map_or(false, |&next| {
358                self.block_max_ends[next] <= self.block_max_ends[block]
359            }) {
360                stack.pop();
361            }
362            self.block_index[block] = stack.last().copied().unwrap_or(block_count);
363            stack.push(block);
364        }
365
366        self.block_prefix_max_ends.clone_from(&self.block_max_ends);
367        for block in 1..block_count {
368            self.block_prefix_max_ends[block] = std::cmp::max(
369                self.block_prefix_max_ends[block - 1],
370                self.block_prefix_max_ends[block],
371            );
372        }
373    }
374
375    /// Insert a new interval after the Lapper has been created. This is very
376    /// inefficient and should be avoided if possible.
377    ///
378    /// SIDE EFFECTS: This clears cov() and overlaps_merged
379    /// meaning that those will have to be recomputed after a insert
380    /// ```
381    /// use rust_lapper::{Lapper, Interval};
382    /// let data : Vec<Interval<usize, usize>>= vec!{
383    ///     Interval{start:0,  stop:5,  val:1},
384    ///     Interval{start:6,  stop:10, val:2},
385    /// };
386    /// let mut lapper = Lapper::new(data);
387    /// lapper.insert(Interval{start:0, stop:20, val:5});
388    /// assert_eq!(lapper.len(), 3);
389    /// assert_eq!(lapper.find(1,3).collect::<Vec<&Interval<usize,usize>>>(),
390    ///     vec![
391    ///         &Interval{start:0, stop:5, val:1},
392    ///         &Interval{start:0, stop:20, val:5},
393    ///     ]
394    /// );
395    ///
396    /// ```
397    pub fn insert(&mut self, elem: Interval<I, T>) {
398        let intervals_insert_index = Self::bsearch_seq_ref(&elem, &self.intervals);
399        self.intervals.insert(intervals_insert_index, elem);
400        self.rebuild_derived();
401        self.cov = None;
402        self.overlaps_merged = false;
403    }
404
405    /// Get the number over intervals in Lapper
406    /// ```
407    /// use rust_lapper::{Lapper, Interval};
408    /// let data = (0..20).step_by(5)
409    ///                   .map(|x| Interval{start: x, stop: x + 10, val: true})
410    ///                   .collect::<Vec<Interval<usize, bool>>>();
411    /// let lapper = Lapper::new(data);
412    /// assert_eq!(lapper.len(), 4);
413    /// ```
414    #[inline]
415    pub fn len(&self) -> usize {
416        self.intervals.len()
417    }
418
419    /// Check if lapper is empty
420    /// ```
421    /// use rust_lapper::{Lapper, Interval};
422    /// let data: Vec<Interval<usize, bool>> = vec![];
423    /// let lapper = Lapper::new(data);
424    /// assert_eq!(lapper.is_empty(), true);
425    /// ```
426    #[inline]
427    pub fn is_empty(&self) -> bool {
428        self.intervals.is_empty()
429    }
430
431    /// Get the number of positions covered by the intervals in Lapper. This provides immutable
432    /// access if it has already been set, or on the fly calculation.
433    /// ```
434    /// use rust_lapper::{Lapper, Interval};
435    /// let data = (0..20).step_by(5)
436    ///                   .map(|x| Interval{start: x, stop: x + 10, val: true})
437    ///                   .collect::<Vec<Interval<usize, bool>>>();
438    /// let lapper = Lapper::new(data);
439    /// assert_eq!(lapper.cov(), 25);
440    #[inline]
441    pub fn cov(&self) -> I {
442        match self.cov {
443            None => self.calculate_coverage(),
444            Some(cov) => cov,
445        }
446    }
447
448    /// Get the number of positions covered by the intervals in Lapper and store it. If you are
449    /// going to be using the coverage, you should set it to avoid calculating it over and over.
450    pub fn set_cov(&mut self) -> I {
451        let cov = self.calculate_coverage();
452        self.cov = Some(cov);
453        cov
454    }
455
456    /// Calculate the actual coverage behind the scenes.
457    fn calculate_coverage(&self) -> I {
458        let mut moving_interval = Interval {
459            start: zero::<I>(),
460            stop: zero::<I>(),
461            val: zero::<I>(),
462        };
463        let mut cov = zero::<I>();
464
465        for interval in self.intervals.iter() {
466            // If it overlaps, embrace, extend, extinguish
467            if moving_interval.overlap(interval.start, interval.stop) {
468                moving_interval.start = std::cmp::min(moving_interval.start, interval.start);
469                moving_interval.stop = std::cmp::max(moving_interval.stop, interval.stop);
470            } else {
471                // add the set and move on
472                cov = cov + (moving_interval.stop - moving_interval.start);
473                moving_interval.start = interval.start;
474                moving_interval.stop = interval.stop;
475            }
476        }
477        // add in the last bit
478        cov = cov + (moving_interval.stop - moving_interval.start);
479        cov
480    }
481
482    /// Return an iterator over the intervals in Lapper
483    #[inline]
484    pub fn iter(&self) -> IterLapper<'_, I, T> {
485        IterLapper {
486            inner: self,
487            pos: 0,
488        }
489    }
490
491    /// Merge any intervals that overlap with each other within the Lapper. This is an easy way to
492    /// speed up queries.
493    pub fn merge_overlaps(&mut self) {
494        let mut stack: VecDeque<&mut Interval<I, T>> = VecDeque::new();
495        let mut ivs = self.intervals.iter_mut();
496        if let Some(first) = ivs.next() {
497            stack.push_back(first);
498            for interval in ivs {
499                let top = stack.pop_back().unwrap();
500                if top.stop < interval.start {
501                    stack.push_back(top);
502                    stack.push_back(interval);
503                } else if top.stop < interval.stop {
504                    top.stop = interval.stop;
505                    //stack.pop_back();
506                    stack.push_back(top);
507                } else {
508                    // they were equal
509                    stack.push_back(top);
510                }
511            }
512            self.overlaps_merged = true;
513            self.intervals = stack
514                .into_iter()
515                .map(|x| Interval {
516                    start: x.start,
517                    stop: x.stop,
518                    val: x.val.clone(),
519                })
520                .collect();
521        }
522        self.rebuild_derived();
523    }
524
525    /// Determine the first index that we should start checking for overlaps for via a binary
526    /// search.
527    /// Assumes that the maximum interval length in `intervals` has been subtracted from
528    /// `start`, otherwise the result is undefined
529    #[inline]
530    pub fn lower_bound(start: I, intervals: &[Interval<I, T>]) -> usize {
531        let mut size = intervals.len();
532        let mut low = 0;
533
534        while size > 0 {
535            let half = size / 2;
536            let other_half = size - half;
537            let probe = low + half;
538            let other_low = low + other_half;
539            let v = &intervals[probe];
540            size = half;
541            low = if v.start < start { other_low } else { low }
542        }
543        low
544    }
545
546    #[inline]
547    pub fn bsearch_seq<K>(key: K, elems: &[K]) -> usize
548    where
549        K: PartialEq + PartialOrd,
550    {
551        Self::bsearch_seq_ref(&key, elems)
552    }
553
554    #[inline]
555    pub fn bsearch_seq_ref<K>(key: &K, elems: &[K]) -> usize
556    where
557        K: PartialEq + PartialOrd,
558    {
559        if elems.is_empty() || elems[0] >= *key {
560            return 0;
561        } else if elems[elems.len() - 1] < *key {
562            return elems.len();
563        }
564
565        let mut cursor = 0;
566        let mut length = elems.len();
567        while length > 1 {
568            let half = length >> 1;
569            length -= half;
570            cursor += (usize::from(elems[cursor + half - 1] < *key)) * half;
571        }
572        cursor
573    }
574
575    /// Return the number of positions in the union and intersection of two Lappers.
576    ///
577    /// The union counts each position covered by either Lapper once. The intersection counts each
578    /// position covered by both Lappers once, regardless of how many intervals cover it.
579    /// ``` rust
580    /// use rust_lapper::{Lapper, Interval};
581    /// type Iv = Interval<u32, u32>;
582    /// let data1: Vec<Iv> = vec![
583    ///     Iv{start: 70, stop: 120, val: 0}, // a long interval
584    ///     Iv{start: 10, stop: 15, val: 0}, // exact overlap
585    ///     Iv{start: 12, stop: 15, val: 0}, // inner overlap
586    ///     Iv{start: 14, stop: 16, val: 0}, // overlap end
587    ///     Iv{start: 68, stop: 71, val: 0}, // overlap start
588    /// ];
589    /// let data2: Vec<Iv> = vec![
590    ///
591    ///     Iv{start: 10, stop: 15, val: 0},
592    ///     Iv{start: 40, stop: 45, val: 0},
593    ///     Iv{start: 50, stop: 55, val: 0},
594    ///     Iv{start: 60, stop: 65, val: 0},
595    ///     Iv{start: 70, stop: 75, val: 0},
596    /// ];
597    ///
598    /// let (mut lapper1, mut lapper2) = (Lapper::new(data1), Lapper::new(data2)) ;
599    /// // Should be the same either way it's calculated
600    /// let (union, intersect) = lapper1.union_and_intersect(&lapper2);
601    /// assert_eq!(intersect, 10);
602    /// assert_eq!(union, 73);
603    /// let (union, intersect) = lapper2.union_and_intersect(&lapper1);
604    /// assert_eq!(intersect, 10);
605    /// assert_eq!(union, 73);
606    /// lapper1.merge_overlaps();
607    /// lapper1.set_cov();
608    /// lapper2.merge_overlaps();
609    /// lapper2.set_cov();
610    ///
611    /// // Should be the same either way it's calculated
612    /// let (union, intersect) = lapper1.union_and_intersect(&lapper2);
613    /// assert_eq!(intersect, 10);
614    /// assert_eq!(union, 73);
615    /// let (union, intersect) = lapper2.union_and_intersect(&lapper1);
616    /// assert_eq!(intersect, 10);
617    /// assert_eq!(union, 73);
618    /// ```
619    #[inline]
620    pub fn union_and_intersect(&self, other: &Self) -> (I, I) {
621        let mut cursor: usize = 0;
622
623        if !self.overlaps_merged || !other.overlaps_merged {
624            let mut intersections: Vec<Interval<I, bool>> = vec![];
625            for self_iv in self.iter() {
626                for other_iv in other.seek(self_iv.start, self_iv.stop, &mut cursor) {
627                    let start = std::cmp::max(self_iv.start, other_iv.start);
628                    let stop = std::cmp::min(self_iv.stop, other_iv.stop);
629                    intersections.push(Interval {
630                        start,
631                        stop,
632                        val: true,
633                    });
634                }
635            }
636            let mut temp_lapper = Lapper::new(intersections);
637            temp_lapper.merge_overlaps();
638            temp_lapper.set_cov();
639            let union = self.cov() + other.cov() - temp_lapper.cov();
640            (union, temp_lapper.cov())
641        } else {
642            let mut intersect = zero::<I>();
643            for c1_iv in self.iter() {
644                for c2_iv in other.seek(c1_iv.start, c1_iv.stop, &mut cursor) {
645                    let local_intersect = c1_iv.intersect(c2_iv);
646                    intersect = intersect + local_intersect;
647                }
648            }
649            let union = self.cov() + other.cov() - intersect;
650            (union, intersect)
651        }
652    }
653
654    /// Find the intersect of two lapper objects.
655    /// Intersect: The number of positions where both lappers intersect. Note that a position only
656    /// counts one time, multiple Intervals covering the same position don't add up
657    #[inline]
658    pub fn intersect(&self, other: &Self) -> I {
659        self.union_and_intersect(other).1
660    }
661
662    /// Find the union of two lapper objects.
663    #[inline]
664    pub fn union(&self, other: &Self) -> I {
665        self.union_and_intersect(other).0
666    }
667
668    /// Return the contiguous intervals of coverage, `val` represents the number of intervals
669    /// covering the returned interval.
670    ///
671    /// # Examples
672    /// ```
673    /// use rust_lapper::{Lapper, Interval};
674    /// let data = (0..20).step_by(5)
675    ///                   .map(|x| Interval{start: x, stop: x + 10, val: true})
676    ///                   .collect::<Vec<Interval<usize, bool>>>();
677    /// let lapper = Lapper::new(data);
678    /// assert_eq!(lapper.depth().collect::<Vec<Interval<usize, usize>>>(), vec![
679    ///             Interval { start: 0, stop: 5, val: 1 },
680    ///             Interval { start: 5, stop: 20, val: 2 },
681    ///             Interval { start: 20, stop: 25, val: 1 }]);
682    /// ```
683    #[inline]
684    pub fn depth(&self) -> IterDepth<'_, I, T> {
685        let mut merged_lapper = Lapper::new(
686            self.intervals
687                .iter()
688                .map(|i| Interval {
689                    start: i.start,
690                    stop: i.stop,
691                    val: true,
692                })
693                .collect::<Vec<Interval<I, bool>>>(),
694        );
695        merged_lapper.merge_overlaps();
696        let merged_len = merged_lapper.intervals.len();
697        IterDepth {
698            inner: self,
699            merged: merged_lapper,
700            curr_merged_pos: zero::<I>(),
701            initialized: false,
702            curr_pos: 0,
703            cursor: 0,
704            end: merged_len,
705        }
706    }
707
708    /// Count all intervals that overlap the half-open query `[start, stop)`.
709    /// This performs two binary searches in order to
710    /// find all the excluded elements, and then deduces the intersection from there. See
711    /// [BITS](https://arxiv.org/pdf/1208.3407.pdf) for more details.
712    /// ```
713    /// use rust_lapper::{Lapper, Interval};
714    /// let lapper = Lapper::new((0..100).step_by(5)
715    ///                                 .map(|x| Interval{start: x, stop: x+2 , val: true})
716    ///                                 .collect::<Vec<Interval<usize, bool>>>());
717    /// assert_eq!(lapper.count(5, 11), 2);
718    /// ```
719    #[inline]
720    pub fn count(&self, start: I, stop: I) -> usize {
721        let len = self.intervals.len();
722        let first = self
723            .stops
724            .partition_point(|interval_stop| *interval_stop <= start);
725        let last = Self::bsearch_seq(stop, &self.starts);
726        let num_cant_after = len - last;
727        len - first - num_cant_after
728    }
729
730    /// Find all intervals that overlap the half-open query `[start, stop)`.
731    /// ```
732    /// use rust_lapper::{Lapper, Interval};
733    /// let lapper = Lapper::new((0..100).step_by(5)
734    ///                                 .map(|x| Interval{start: x, stop: x+2 , val: true})
735    ///                                 .collect::<Vec<Interval<usize, bool>>>());
736    /// assert_eq!(lapper.find(5, 11).count(), 2);
737    /// ```
738    #[inline]
739    pub fn find(&self, start: I, stop: I) -> IterFind<'_, I, T> {
740        let off = self
741            .block_prefix_max_ends
742            .partition_point(|max_end| *max_end <= start)
743            * INDEX_BLOCK_SIZE;
744        IterFind {
745            inner: self,
746            next_block_start: off,
747            mask_block_start: 0,
748            mask: 0,
749            dense_next: 0,
750            dense_end: 0,
751            backend: detect_backend(),
752            start,
753            stop,
754        }
755    }
756
757    /// Find all intervals that overlap the half-open query `[start, stop)`.
758    ///
759    /// Use this method when query starts arrive in nondecreasing order. A caller-owned cursor
760    /// narrows the first candidate block, after which `seek()` uses the same block traversal as
761    /// [`Lapper::find`]. Keeping the cursor outside `Lapper` allows immutable queries and preserves
762    /// `Sync` when `T` and `I` are `Sync`.
763    /// ```
764    /// use rust_lapper::{Lapper, Interval};
765    /// let lapper = Lapper::new((0..100).step_by(5)
766    ///                                 .map(|x| Interval{start: x, stop: x+2 , val: true})
767    ///                                 .collect::<Vec<Interval<usize, bool>>>());
768    /// let mut cursor = 0;
769    /// for i in lapper.iter() {
770    ///    assert_eq!(lapper.seek(i.start, i.stop, &mut cursor).count(), 1);
771    /// }
772    /// ```
773    #[inline]
774    pub fn seek<'a>(&'a self, start: I, stop: I, cursor: &mut usize) -> IterFind<'a, I, T> {
775        if self.max_len_overflowed {
776            *cursor = self
777                .block_prefix_max_ends
778                .partition_point(|max_end| *max_end <= start)
779                * INDEX_BLOCK_SIZE;
780        } else {
781            let earliest_start = start
782                .checked_sub(&self.max_len)
783                .unwrap_or_else(I::min_value);
784            if *cursor == 0
785                || (*cursor < self.intervals.len() && self.intervals[*cursor].start > start)
786            {
787                *cursor = Self::lower_bound(earliest_start, &self.intervals);
788            }
789
790            while *cursor + 1 < self.intervals.len()
791                && self.intervals[*cursor + 1].start < earliest_start
792            {
793                *cursor += 1;
794            }
795        }
796
797        IterFind {
798            inner: self,
799            next_block_start: (*cursor / INDEX_BLOCK_SIZE) * INDEX_BLOCK_SIZE,
800            mask_block_start: 0,
801            mask: 0,
802            dense_next: 0,
803            dense_end: 0,
804            backend: detect_backend(),
805            start,
806            stop,
807        }
808    }
809}
810
811/// Find Iterator
812#[derive(Debug)]
813pub struct IterFind<'a, I, T>
814where
815    T: Eq + Clone + Send + Sync + 'a,
816    I: PrimInt + Ord + Clone + Send + Sync,
817{
818    inner: &'a Lapper<I, T>,
819    next_block_start: usize,
820    mask_block_start: usize,
821    mask: u32,
822    dense_next: usize,
823    dense_end: usize,
824    backend: MaskBackend,
825    start: I,
826    stop: I,
827}
828
829impl<'a, I, T> IterFind<'a, I, T>
830where
831    T: Eq + Clone + Send + Sync + 'a,
832    I: PrimInt + Ord + Clone + Send + Sync + 'static,
833{
834    #[inline(always)]
835    fn next_blockwise(&mut self) -> Option<&'a Interval<I, T>> {
836        loop {
837            // Return the next pending match from the dense branch.
838            if self.dense_next < self.dense_end {
839                let index = self.dense_next;
840                self.dense_next += 1;
841                return Some(&self.inner.intervals[index]);
842            }
843
844            // Return the next pending match from a mixed block's mask.
845            if self.mask != 0 {
846                let lane = self.mask.trailing_zeros() as usize;
847                self.mask &= self.mask - 1;
848                return Some(&self.inner.intervals[self.mask_block_start + lane]);
849            }
850
851            let block_start = self.next_block_start;
852            // No blocks remain, so there are no more matches.
853            if block_start >= self.inner.starts.len() {
854                return None;
855            }
856
857            // Private arrays are rebuilt together by constructors, mutations,
858            // and deserialization. Public interval edits cannot extend this bound.
859            // Starts are sorted, so no interval in this or a later block can match.
860            if unsafe { *self.inner.starts.get_unchecked(block_start) } >= self.stop {
861                return None;
862            }
863
864            let block = block_start / INDEX_BLOCK_SIZE;
865            // No ends in this block reach past the query start. Skip to the next
866            // block whose maximum end might match.
867            if unsafe { *self.inner.block_max_ends.get_unchecked(block) } <= self.start {
868                let next_block = unsafe { *self.inner.block_index.get_unchecked(block) };
869                debug_assert!(
870                    next_block <= self.inner.block_index.len(),
871                    "Lapper block index is corrupt"
872                );
873                self.next_block_start = next_block * INDEX_BLOCK_SIZE;
874                continue;
875            }
876
877            let block_end = (block_start + INDEX_BLOCK_SIZE).min(self.inner.starts.len());
878            // All ends match. Take the dense branch for the prefix whose starts
879            // are before the query stop.
880            if unsafe { *self.inner.block_min_ends.get_unchecked(block) } > self.start {
881                let starts = unsafe { self.inner.starts.get_unchecked(block_start..block_end) };
882                // If the last start matches, the whole block is dense. Otherwise,
883                // find the matching prefix.
884                let active_len = if unsafe { *starts.get_unchecked(starts.len() - 1) } < self.stop {
885                    starts.len()
886                } else {
887                    starts.partition_point(|lane_start| *lane_start < self.stop)
888                };
889                self.dense_next = block_start;
890                self.dense_end = block_start + active_len;
891                // Continue after a full block. A partial prefix means every later
892                // start is outside the query.
893                self.next_block_start = if active_len == starts.len() {
894                    block_end
895                } else {
896                    self.inner.starts.len()
897                };
898                continue;
899            }
900
901            // Some ends match. Build the exact overlap mask for this mixed block.
902            self.mask_block_start = block_start;
903            self.next_block_start = block_end;
904            self.mask = overlap_mask(
905                self.backend,
906                unsafe { self.inner.starts.get_unchecked(block_start..block_end) },
907                unsafe {
908                    self.inner
909                        .stops_by_start
910                        .get_unchecked(block_start..block_end)
911                },
912                self.start,
913                self.stop,
914            );
915        }
916    }
917}
918
919impl<'a, I, T> Iterator for IterFind<'a, I, T>
920where
921    T: Eq + Clone + Send + Sync + 'a,
922    I: PrimInt + Ord + Clone + Send + Sync + 'static,
923{
924    type Item = &'a Interval<I, T>;
925
926    #[inline]
927    fn next(&mut self) -> Option<Self::Item> {
928        self.next_blockwise()
929    }
930}
931
932/// Depth Iterator
933#[derive(Debug)]
934pub struct IterDepth<'a, I, T>
935where
936    T: Eq + Clone + Send + Sync + 'a,
937    I: PrimInt + Ord + Clone + Send + Sync,
938{
939    inner: &'a Lapper<I, T>,
940    merged: Lapper<I, bool>, // A lapper that is the merged_lapper of inner
941    curr_merged_pos: I,      // Current start position in current interval
942    initialized: bool,
943    curr_pos: usize, // In merged list of non-overlapping intervals
944    cursor: usize,   // cursor for seek over inner lapper
945    end: usize,      // len of merged
946}
947
948impl<'a, I, T> Iterator for IterDepth<'a, I, T>
949where
950    T: Eq + Clone + Send + Sync + 'a,
951    I: PrimInt + Ord + Clone + Send + Sync + 'static,
952{
953    type Item = Interval<I, I>;
954
955    #[inline]
956    fn next(&mut self) -> Option<Self::Item> {
957        let mut interval: &Interval<I, bool> = &self.merged.intervals[self.curr_pos];
958        if !self.initialized {
959            self.curr_merged_pos = interval.start;
960            self.initialized = true;
961        }
962        if interval.stop == self.curr_merged_pos {
963            if self.curr_pos + 1 != self.end {
964                self.curr_pos += 1;
965                interval = &self.merged.intervals[self.curr_pos];
966                self.curr_merged_pos = interval.start;
967            } else {
968                return None;
969            }
970        }
971        let start = self.curr_merged_pos;
972        let depth_at_point = self
973            .inner
974            .seek(
975                self.curr_merged_pos,
976                self.curr_merged_pos + one::<I>(),
977                &mut self.cursor,
978            )
979            .count();
980        let mut new_depth_at_point = depth_at_point;
981        while new_depth_at_point == depth_at_point && self.curr_merged_pos < interval.stop {
982            self.curr_merged_pos = self.curr_merged_pos + one::<I>();
983            if self.curr_merged_pos == interval.stop {
984                break;
985            }
986            new_depth_at_point = self
987                .inner
988                .seek(
989                    self.curr_merged_pos,
990                    self.curr_merged_pos + one::<I>(),
991                    &mut self.cursor,
992                )
993                .count();
994        }
995        Some(Interval {
996            start,
997            stop: self.curr_merged_pos,
998            val: I::from(depth_at_point).unwrap(), // from usize should always work
999        })
1000    }
1001}
1002/// Lapper Iterator
1003pub struct IterLapper<'a, I, T>
1004where
1005    T: Eq + Clone + Send + Sync + 'a,
1006    I: PrimInt + Ord + Clone + Send + Sync,
1007{
1008    inner: &'a Lapper<I, T>,
1009    pos: usize,
1010}
1011
1012impl<'a, I, T> Iterator for IterLapper<'a, I, T>
1013where
1014    T: Eq + Clone + Send + Sync + 'a,
1015    I: PrimInt + Ord + Clone + Send + Sync,
1016{
1017    type Item = &'a Interval<I, T>;
1018
1019    fn next(&mut self) -> Option<Self::Item> {
1020        if self.pos >= self.inner.intervals.len() {
1021            None
1022        } else {
1023            self.pos += 1;
1024            self.inner.intervals.get(self.pos - 1)
1025        }
1026    }
1027}
1028
1029impl<I, T> IntoIterator for Lapper<I, T>
1030where
1031    T: Eq + Clone + Send + Sync,
1032    I: PrimInt + Ord + Clone + Send + Sync,
1033{
1034    type Item = Interval<I, T>;
1035    type IntoIter = ::std::vec::IntoIter<Self::Item>;
1036
1037    fn into_iter(self) -> Self::IntoIter {
1038        self.intervals.into_iter()
1039    }
1040}
1041
1042impl<'a, I, T> IntoIterator for &'a Lapper<I, T>
1043where
1044    T: Eq + Clone + Send + Sync + 'a,
1045    I: PrimInt + Ord + Clone + Send + Sync,
1046{
1047    type Item = &'a Interval<I, T>;
1048    type IntoIter = std::slice::Iter<'a, Interval<I, T>>;
1049
1050    fn into_iter(self) -> std::slice::Iter<'a, Interval<I, T>> {
1051        self.intervals.iter()
1052    }
1053}
1054
1055impl<'a, I, T> IntoIterator for &'a mut Lapper<I, T>
1056where
1057    T: Eq + Clone + Send + Sync + 'a,
1058    I: PrimInt + Ord + Clone + Send + Sync,
1059{
1060    type Item = &'a mut Interval<I, T>;
1061    type IntoIter = std::slice::IterMut<'a, Interval<I, T>>;
1062
1063    fn into_iter(self) -> std::slice::IterMut<'a, Interval<I, T>> {
1064        self.intervals.iter_mut()
1065    }
1066}
1067
1068#[cfg(test)]
1069#[rustfmt::skip]
1070mod tests {
1071    use super::*;
1072
1073    type Iv = Interval<usize, u32>;
1074    fn setup_nonoverlapping() -> Lapper<usize, u32> {
1075        let data: Vec<Iv> = (0..100)
1076            .step_by(20)
1077            .map(|x| Iv {
1078                start: x,
1079                stop: x + 10,
1080                val: 0,
1081            })
1082            .collect();
1083        Lapper::new(data)
1084    }
1085
1086    fn setup_overlapping() -> Lapper<usize, u32> {
1087        let data: Vec<Iv> = (0..100)
1088            .step_by(10)
1089            .map(|x| Iv {
1090                start: x,
1091                stop: x + 15,
1092                val: 0,
1093            })
1094            .collect();
1095        Lapper::new(data)
1096    }
1097
1098    fn setup_badlapper() -> Lapper<usize, u32> {
1099        let data: Vec<Iv> = vec![
1100            Iv{start: 70, stop: 120, val: 0}, // max_len = 50
1101            Iv{start: 10, stop: 15, val: 0},
1102            Iv{start: 10, stop: 15, val: 0}, // exact overlap
1103            Iv{start: 12, stop: 15, val: 0}, // inner overlap
1104            Iv{start: 14, stop: 16, val: 0}, // overlap end
1105            Iv{start: 40, stop: 45, val: 0},
1106            Iv{start: 50, stop: 55, val: 0},
1107            Iv{start: 60, stop: 65, val: 0},
1108            Iv{start: 68, stop: 71, val: 0}, // overlap start
1109            Iv{start: 70, stop: 75, val: 0},
1110        ];
1111        Lapper::new(data)
1112    }
1113
1114    fn setup_single() -> Lapper<usize, u32> {
1115        let data: Vec<Iv> = vec![Iv {
1116            start: 10,
1117            stop: 35,
1118            val: 0,
1119        }];
1120        Lapper::new(data)
1121    }
1122
1123    // Test that inserting data ends up with the same lapper (nonoverlapping)
1124    #[test]
1125    fn insert_equality_nonoverlapping() {
1126        let data: Vec<Iv> = (0..100)
1127            .step_by(20)
1128            .map(|x| Iv {
1129                start: x,
1130                stop: x + 10,
1131                val: 0,
1132            })
1133            .collect();
1134        let new_lapper = Lapper::new(data.clone());
1135        let mut insert_lapper = Lapper::new(vec![]);
1136        for elem in data {
1137            insert_lapper.insert(elem);
1138        }
1139        assert_eq!(new_lapper.starts, insert_lapper.starts);
1140        assert_eq!(new_lapper.stops, insert_lapper.stops);
1141        assert_eq!(new_lapper.intervals, insert_lapper.intervals);
1142        assert_eq!(new_lapper.max_len, insert_lapper.max_len);
1143    }
1144
1145    // Test that inserting data ends up with the same lapper (overlapping)
1146    #[test]
1147    fn insert_equality_overlapping() {
1148        let data: Vec<Iv> = (0..100)
1149            .step_by(10)
1150            .map(|x| Iv {
1151                start: x,
1152                stop: x + 15,
1153                val: 0,
1154            })
1155            .collect();
1156        let new_lapper = Lapper::new(data.clone());
1157        let mut insert_lapper = Lapper::new(vec![]);
1158        for elem in data {
1159            insert_lapper.insert(elem);
1160        }
1161        assert_eq!(new_lapper.starts, insert_lapper.starts);
1162        assert_eq!(new_lapper.stops, insert_lapper.stops);
1163        assert_eq!(new_lapper.intervals, insert_lapper.intervals);
1164        assert_eq!(new_lapper.max_len, insert_lapper.max_len);
1165    }
1166
1167    // Test that inserting data half with new and half with insert
1168    // ends up with the same lapper
1169    #[test]
1170    fn insert_equality_half_and_half() {
1171        let data: Vec<Iv> = (0..100)
1172            .step_by(1)
1173            .map(|x| Iv {
1174                start: x,
1175                stop: x + 15,
1176                val: 0,
1177            })
1178            .collect();
1179        let new_lapper = Lapper::new(data.clone());
1180        let (new_data, insert_data) = data.split_at(50);
1181        let mut insert_lapper = Lapper::new(new_data.to_vec());
1182        let mut insert_data = insert_data.to_vec();
1183        insert_data.reverse();
1184        for elem in insert_data {
1185            insert_lapper.insert(elem);
1186        }
1187        assert_eq!(new_lapper.starts, insert_lapper.starts);
1188        assert_eq!(new_lapper.stops, insert_lapper.stops);
1189        assert_eq!(new_lapper.intervals, insert_lapper.intervals);
1190        assert_eq!(new_lapper.max_len, insert_lapper.max_len);
1191    }
1192
1193    // Test that inserting data ends up with the same lapper (badlapper)
1194    #[test]
1195    fn insert_equality_badlapper() {
1196        let data: Vec<Iv> = vec![
1197            Iv{start: 70, stop: 120, val: 0}, // max_len = 50
1198            Iv{start: 10, stop: 15, val: 0},
1199            Iv{start: 10, stop: 15, val: 0}, // exact overlap
1200            Iv{start: 12, stop: 15, val: 0}, // inner overlap
1201            Iv{start: 14, stop: 16, val: 0}, // overlap end
1202            Iv{start: 40, stop: 45, val: 0},
1203            Iv{start: 50, stop: 55, val: 0},
1204            Iv{start: 60, stop: 65, val: 0},
1205            Iv{start: 68, stop: 71, val: 0}, // overlap start
1206            Iv{start: 70, stop: 75, val: 0},
1207        ];
1208        let new_lapper = Lapper::new(data.clone());
1209        let mut insert_lapper = Lapper::new(vec![]);
1210        for elem in data {
1211            insert_lapper.insert(elem);
1212        }
1213        assert_eq!(new_lapper.starts, insert_lapper.starts);
1214        assert_eq!(new_lapper.stops, insert_lapper.stops);
1215        assert_eq!(new_lapper.intervals, insert_lapper.intervals);
1216        assert_eq!(new_lapper.max_len, insert_lapper.max_len);
1217    }
1218
1219    // Test that inserting data ends up with the same lapper (single)
1220    #[test]
1221    fn insert_equality_single() {
1222        let data: Vec<Iv> = vec![Iv {
1223            start: 10,
1224            stop: 35,
1225            val: 0,
1226        }];
1227        let new_lapper = Lapper::new(data.clone());
1228        let mut insert_lapper = Lapper::new(vec![]);
1229        for elem in data {
1230            insert_lapper.insert(elem);
1231        }
1232        assert_eq!(new_lapper.starts, insert_lapper.starts);
1233        assert_eq!(new_lapper.stops, insert_lapper.stops);
1234        assert_eq!(new_lapper.intervals, insert_lapper.intervals);
1235        assert_eq!(new_lapper.max_len, insert_lapper.max_len);
1236    }
1237
1238    // Test that a query stop that hits an interval start returns no interval
1239    #[test]
1240    fn test_query_stop_interval_start() {
1241        let lapper = setup_nonoverlapping();
1242        let mut cursor = 0;
1243        assert_eq!(None, lapper.find(15, 20).next());
1244        assert_eq!(None, lapper.seek(15, 20, &mut cursor).next());
1245        assert_eq!(lapper.find(15, 20).count(), lapper.count(15, 20));
1246    }
1247
1248    // Test that a query start that hits an interval end returns no interval
1249    #[test]
1250    fn test_query_start_interval_stop() {
1251        let lapper = setup_nonoverlapping();
1252        let mut cursor = 0;
1253        assert_eq!(None, lapper.find(30, 35).next());
1254        assert_eq!(None, lapper.seek(30, 35, &mut cursor).next());
1255        assert_eq!(lapper.find(30, 35).count(), lapper.count(30, 35));
1256    }
1257
1258    // Test that a query that overlaps the start of an interval returns that interval
1259    #[test]
1260    fn test_query_overlaps_interval_start() {
1261        let lapper = setup_nonoverlapping();
1262        let mut cursor = 0;
1263        let expected = Iv {
1264            start: 20,
1265            stop: 30,
1266            val: 0,
1267        };
1268        assert_eq!(Some(&expected), lapper.find(15, 25).next());
1269        assert_eq!(Some(&expected), lapper.seek(15, 25, &mut cursor).next());
1270        assert_eq!(lapper.find(15, 25).count(), lapper.count(15, 25));
1271    }
1272
1273    // Test that a query that overlaps the stop of an interval returns that interval
1274    #[test]
1275    fn test_query_overlaps_interval_stop() {
1276        let lapper = setup_nonoverlapping();
1277        let mut cursor = 0;
1278        let expected = Iv {
1279            start: 20,
1280            stop: 30,
1281            val: 0,
1282        };
1283        assert_eq!(Some(&expected), lapper.find(25, 35).next());
1284        assert_eq!(Some(&expected), lapper.seek(25, 35, &mut cursor).next());
1285        assert_eq!(lapper.find(25, 35).count(), lapper.count(25, 35));
1286    }
1287
1288    // Test that a query that is enveloped by interval returns interval
1289    #[test]
1290    fn test_interval_envelops_query() {
1291        let lapper = setup_nonoverlapping();
1292        let mut cursor = 0;
1293        let expected = Iv {
1294            start: 20,
1295            stop: 30,
1296            val: 0,
1297        };
1298        assert_eq!(Some(&expected), lapper.find(22, 27).next());
1299        assert_eq!(Some(&expected), lapper.seek(22, 27, &mut cursor).next());
1300        assert_eq!(lapper.find(22, 27).count(), lapper.count(22, 27));
1301    }
1302
1303    // Test that a query that envolops an interval returns that interval
1304    #[test]
1305    fn test_query_envolops_interval() {
1306        let lapper = setup_nonoverlapping();
1307        let mut cursor = 0;
1308        let expected = Iv {
1309            start: 20,
1310            stop: 30,
1311            val: 0,
1312        };
1313        assert_eq!(Some(&expected), lapper.find(15, 35).next());
1314        assert_eq!(Some(&expected), lapper.seek(15, 35, &mut cursor).next());
1315        assert_eq!(lapper.find(15, 35).count(), lapper.count(15, 35));
1316    }
1317
1318    #[test]
1319    fn test_overlapping_intervals() {
1320        let lapper = setup_overlapping();
1321        let mut cursor = 0;
1322        let e1 = Iv {
1323            start: 0,
1324            stop: 15,
1325            val: 0,
1326        };
1327        let e2 = Iv {
1328            start: 10,
1329            stop: 25,
1330            val: 0,
1331        };
1332        assert_eq!(vec![&e1, &e2], lapper.find(8, 20).collect::<Vec<&Iv>>());
1333        assert_eq!(
1334            vec![&e1, &e2],
1335            lapper.seek(8, 20, &mut cursor).collect::<Vec<&Iv>>()
1336        );
1337        assert_eq!(lapper.count(8, 20), 2);
1338    }
1339
1340    #[test]
1341    fn test_merge_overlaps() {
1342        let mut lapper = setup_badlapper();
1343        let expected: Vec<&Iv> = vec![
1344            &Iv{start: 10, stop: 16, val: 0},
1345            &Iv{start: 40, stop: 45, val: 0},
1346            &Iv{start: 50, stop: 55, val: 0},
1347            &Iv{start: 60, stop: 65, val: 0},
1348            &Iv{start: 68, stop: 120, val: 0}, // max_len = 50
1349        ];
1350        assert_eq!(lapper.intervals.len(), lapper.starts.len());
1351        lapper.merge_overlaps();
1352        assert_eq!(expected, lapper.iter().collect::<Vec<&Iv>>());
1353        assert_eq!(lapper.intervals.len(), lapper.starts.len())
1354
1355    }
1356
1357    // This test was added because this breakage was found in a library user's code, where after
1358    // calling merge_overlaps(), the find() call returned an empty iterator.
1359    #[test]
1360    fn test_merge_overlaps_find() {
1361        let data = vec![
1362                Iv{start: 2, stop: 3, val: 0},
1363                Iv{start: 3, stop: 4, val: 0},
1364                Iv{start: 4, stop: 6, val: 0},
1365                Iv{start: 6, stop: 7, val: 0},
1366                Iv{start: 7, stop: 8, val: 0},
1367        ];
1368        let mut lapper = Lapper::new(data);
1369
1370        let found = lapper.find(7, 9).collect::<Vec<&Interval<_,_>>>();
1371        assert_eq!(found, vec![
1372            &Iv{start:7, stop: 8, val: 0},
1373        ]);
1374
1375        // merge_overlaps should merge all intervals to one, which should be returned in the find call.
1376        lapper.merge_overlaps();
1377
1378        let found = lapper.find(7, 9).collect::<Vec<&Interval<_,_>>>();
1379        assert_eq!(found, vec![
1380            &Iv{start:2, stop: 8, val: 0},
1381        ]);
1382    }
1383
1384    #[test]
1385    fn test_lapper_cov() {
1386        let mut lapper = setup_badlapper();
1387        let before = lapper.cov();
1388        lapper.merge_overlaps();
1389        let after = lapper.cov();
1390        assert_eq!(before, after);
1391
1392        let mut lapper = setup_nonoverlapping();
1393        lapper.set_cov();
1394        assert_eq!(lapper.cov(), 50);
1395    }
1396
1397    #[test]
1398    fn test_interval_intersects() {
1399        let i1 = Iv{start: 70, stop: 120, val: 0}; // max_len = 50
1400        let i2 = Iv{start: 10, stop: 15, val: 0};
1401        let i3 = Iv{start: 10, stop: 15, val: 0}; // exact overlap
1402        let i4 = Iv{start: 12, stop: 15, val: 0}; // inner overlap
1403        let i5 = Iv{start: 14, stop: 16, val: 0}; // overlap end
1404        let i6 = Iv{start: 40, stop: 50, val: 0};
1405        let i7 = Iv{start: 50, stop: 55, val: 0};
1406        let i_8 = Iv{start: 60, stop: 65, val: 0};
1407        let i9 = Iv{start: 68, stop: 71, val: 0}; // overlap start
1408        let i10 = Iv{start: 70, stop: 75, val: 0};
1409
1410        assert_eq!(i2.intersect(&i3), 5); // exact match
1411        assert_eq!(i2.intersect(&i4), 3); // inner intersect
1412        assert_eq!(i2.intersect(&i5), 1); // end intersect
1413        assert_eq!(i9.intersect(&i10), 1); // start intersect
1414        assert_eq!(i7.intersect(&i_8), 0); // no intersect
1415        assert_eq!(i6.intersect(&i7), 0); // no intersect stop = start
1416        assert_eq!(i1.intersect(&i10), 5); // inner intersect at start
1417    }
1418
1419    #[test]
1420    fn test_union_and_intersect() {
1421        let data1: Vec<Iv> = vec![
1422            Iv{start: 70, stop: 120, val: 0}, // max_len = 50
1423            Iv{start: 10, stop: 15, val: 0}, // exact overlap
1424            Iv{start: 12, stop: 15, val: 0}, // inner overlap
1425            Iv{start: 14, stop: 16, val: 0}, // overlap end
1426            Iv{start: 68, stop: 71, val: 0}, // overlap start
1427        ];
1428        let data2: Vec<Iv> = vec![
1429
1430            Iv{start: 10, stop: 15, val: 0},
1431            Iv{start: 40, stop: 45, val: 0},
1432            Iv{start: 50, stop: 55, val: 0},
1433            Iv{start: 60, stop: 65, val: 0},
1434            Iv{start: 70, stop: 75, val: 0},
1435        ];
1436
1437        let (mut lapper1, mut lapper2) = (Lapper::new(data1), Lapper::new(data2)) ;
1438        // Should be the same either way it's calculated
1439        let (union, intersect) = lapper1.union_and_intersect(&lapper2);
1440        assert_eq!(intersect, 10);
1441        assert_eq!(union, 73);
1442        let (union, intersect) = lapper2.union_and_intersect(&lapper1);
1443        assert_eq!(intersect, 10);
1444        assert_eq!(union, 73);
1445        lapper1.merge_overlaps();
1446        lapper1.set_cov();
1447        lapper2.merge_overlaps();
1448        lapper2.set_cov();
1449
1450        // Should be the same either way it's calculated
1451        let (union, intersect) = lapper1.union_and_intersect(&lapper2);
1452        assert_eq!(intersect, 10);
1453        assert_eq!(union, 73);
1454        let (union, intersect) = lapper2.union_and_intersect(&lapper1);
1455        assert_eq!(intersect, 10);
1456        assert_eq!(union, 73);
1457    }
1458
1459    #[test]
1460    fn test_find_overlaps_in_large_intervals() {
1461        let data1: Vec<Iv> = vec![
1462            Iv{start: 0, stop: 8, val: 0},
1463            Iv{start: 1, stop: 10, val: 0},
1464            Iv{start: 2, stop: 5, val: 0},
1465            Iv{start: 3, stop: 8, val: 0},
1466            Iv{start: 4, stop: 7, val: 0},
1467            Iv{start: 5, stop: 8, val: 0},
1468            Iv{start: 8, stop: 8, val: 0},
1469            Iv{start: 9, stop: 11, val: 0},
1470            Iv{start: 10, stop: 13, val: 0},
1471            Iv{start: 100, stop: 200, val: 0},
1472            Iv{start: 110, stop: 120, val: 0},
1473            Iv{start: 110, stop: 124, val: 0},
1474            Iv{start: 111, stop: 160, val: 0},
1475            Iv{start: 150, stop: 200, val: 0},
1476        ];
1477        let lapper = Lapper::new(data1);
1478        let found = lapper.find(8, 11).collect::<Vec<&Iv>>();
1479        assert_eq!(found, vec![
1480            &Iv{start: 1, stop: 10, val: 0},
1481            &Iv{start: 9, stop: 11, val: 0},
1482            &Iv{start: 10, stop: 13, val: 0},
1483        ]);
1484        assert_eq!(lapper.count(8, 11), 3);
1485        let found = lapper.find(145, 151).collect::<Vec<&Iv>>();
1486        assert_eq!(found, vec![
1487            &Iv{start: 100, stop: 200, val: 0},
1488            &Iv{start: 111, stop: 160, val: 0},
1489            &Iv{start: 150, stop: 200, val: 0},
1490        ]);
1491
1492        assert_eq!(lapper.count(145, 151), 3);
1493    }
1494
1495    #[test]
1496    fn test_depth_sanity() {
1497        let data1: Vec<Iv> = vec![
1498            Iv{start: 0, stop: 10, val: 0},
1499            Iv{start: 5, stop: 10, val: 0}
1500        ];
1501        let lapper = Lapper::new(data1);
1502        let found = lapper.depth().collect::<Vec<Interval<usize, usize>>>();
1503        assert_eq!(found, vec![
1504                   Interval{start: 0, stop: 5, val: 1},
1505                   Interval{start: 5, stop: 10, val: 2}
1506        ]);
1507    }
1508
1509    #[test]
1510    fn test_depth_hard() {
1511        let data1: Vec<Iv> = vec![
1512            Iv{start: 1, stop: 10, val: 0},
1513            Iv{start: 2, stop: 5, val: 0},
1514            Iv{start: 3, stop: 8, val: 0},
1515            Iv{start: 3, stop: 8, val: 0},
1516            Iv{start: 3, stop: 8, val: 0},
1517            Iv{start: 5, stop: 8, val: 0},
1518            Iv{start: 9, stop: 11, val: 0},
1519        ];
1520        let lapper = Lapper::new(data1);
1521        let found = lapper.depth().collect::<Vec<Interval<usize, usize>>>();
1522        assert_eq!(found, vec![
1523                   Interval{start: 1, stop: 2, val: 1},
1524                   Interval{start: 2, stop: 3, val: 2},
1525                   Interval{start: 3, stop: 8, val: 5},
1526                   Interval{start: 8, stop: 9, val: 1},
1527                   Interval{start: 9, stop: 10, val: 2},
1528                   Interval{start: 10, stop: 11, val: 1},
1529        ]);
1530    }
1531    #[test]
1532    fn test_depth_harder() {
1533        let data1: Vec<Iv> = vec![
1534            Iv{start: 1, stop: 10, val: 0},
1535            Iv{start: 2, stop: 5, val: 0},
1536            Iv{start: 3, stop: 8, val: 0},
1537            Iv{start: 3, stop: 8, val: 0},
1538            Iv{start: 3, stop: 8, val: 0},
1539            Iv{start: 5, stop: 8, val: 0},
1540            Iv{start: 9, stop: 11, val: 0},
1541            Iv{start: 15, stop: 20, val: 0},
1542        ];
1543        let lapper = Lapper::new(data1);
1544        let found = lapper.depth().collect::<Vec<Interval<usize, usize>>>();
1545        assert_eq!(found, vec![
1546                   Interval{start: 1, stop: 2, val: 1},
1547                   Interval{start: 2, stop: 3, val: 2},
1548                   Interval{start: 3, stop: 8, val: 5},
1549                   Interval{start: 8, stop: 9, val: 1},
1550                   Interval{start: 9, stop: 10, val: 2},
1551                   Interval{start: 10, stop: 11, val: 1},
1552                   Interval{start: 15, stop: 20, val: 1},
1553        ]);
1554    }
1555    // BUG TESTS - these are tests that came from real life
1556
1557    // Test that it's not possible to induce index out of bounds by pushing the cursor past the end
1558    // of the lapper.
1559    #[test]
1560    fn test_seek_over_len() {
1561        let lapper = setup_nonoverlapping();
1562        let single = setup_single();
1563        let mut cursor: usize = 0;
1564
1565        for interval in lapper.iter() {
1566            for o_interval in single.seek(interval.start, interval.stop, &mut cursor) {
1567                println!("{:#?}", o_interval);
1568            }
1569        }
1570    }
1571
1572    // Test that if lower_bound puts us before the first match, we still return a match
1573    #[test]
1574    fn test_find_over_behind_first_match() {
1575        let lapper = setup_badlapper();
1576        let e1 = Iv {start: 50, stop: 55, val: 0};
1577        let found = lapper.find(50, 55).next();
1578        assert_eq!(found, Some(&e1));
1579        assert_eq!(lapper.find(50, 55).count(), lapper.count(50,55));
1580    }
1581
1582    // When there is a very long interval that spans many little intervals, test that the little
1583    // Intervals still get returned properly.
1584    #[test]
1585    fn test_bad_skips() {
1586        let data = vec![
1587            Iv{start:25264912, stop: 25264986, val: 0},
1588            Iv{start:27273024, stop: 27273065	, val: 0},
1589            Iv{start:27440273, stop: 27440318	, val: 0},
1590            Iv{start:27488033, stop: 27488125	, val: 0},
1591            Iv{start:27938410, stop: 27938470	, val: 0},
1592            Iv{start:27959118, stop: 27959171	, val: 0},
1593            Iv{start:28866309, stop: 33141404	, val: 0},
1594        ];
1595        let lapper = Lapper::new(data);
1596
1597        let found = lapper.find(28974798, 33141355).collect::<Vec<&Iv>>();
1598        assert_eq!(found, vec![
1599            &Iv{start:28866309, stop: 33141404	, val: 0},
1600        ]);
1601        assert_eq!(lapper.count(28974798, 33141355), 1);
1602    }
1603
1604    #[cfg(feature = "with_serde")]
1605    #[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
1606    struct LegacyLapper {
1607        intervals: Vec<Iv>,
1608        starts: Vec<usize>,
1609        stops: Vec<usize>,
1610        max_len: usize,
1611        cov: Option<usize>,
1612        overlaps_merged: bool,
1613    }
1614
1615    #[cfg(feature = "with_serde")]
1616    #[test]
1617    fn serde_keeps_the_v1_six_field_representation() {
1618        let data = vec![
1619            Iv{start:25264912, stop: 25264986, val: 0},
1620            Iv{start:27273024, stop: 27273065	, val: 0},
1621            Iv{start:27440273, stop: 27440318	, val: 0},
1622            Iv{start:27488033, stop: 27488125	, val: 0},
1623            Iv{start:27938410, stop: 27938470	, val: 0},
1624            Iv{start:27959118, stop: 27959171	, val: 0},
1625            Iv{start:28866309, stop: 33141404	, val: 0},
1626        ];
1627        let lapper = Lapper::new(data);
1628
1629        let legacy = LegacyLapper {
1630            intervals: lapper.intervals.clone(),
1631            starts: lapper.starts.clone(),
1632            stops: lapper.stops.clone(),
1633            max_len: lapper.max_len,
1634            cov: lapper.cov,
1635            overlaps_merged: lapper.overlaps_merged,
1636        };
1637        let legacy_bytes = bincode::serialize(&legacy).unwrap();
1638        let deserialized: Lapper<usize, u32> = bincode::deserialize(&legacy_bytes).unwrap();
1639        let current_bytes = bincode::serialize(&deserialized).unwrap();
1640        assert_eq!(current_bytes, legacy_bytes);
1641        let legacy_again: LegacyLapper = bincode::deserialize(&current_bytes).unwrap();
1642        assert_eq!(legacy_again, legacy);
1643
1644        let found = deserialized.find(28974798, 33141355).collect::<Vec<&Iv>>();
1645        assert_eq!(found, vec![
1646            &Iv{start:28866309, stop: 33141404	, val: 0},
1647        ]);
1648        assert_eq!(deserialized.count(28974798, 33141355), 1);
1649    }
1650
1651}