1use std::collections::VecDeque;
58use std::convert::TryFrom;
59use std::ops::Range;
60
61use itertools::Itertools;
62
63pub trait Interval {
67 type Coord: Ord;
69
70 fn start(&self) -> &Self::Coord;
72
73 fn end(&self) -> &Self::Coord;
75}
76
77impl<N> Interval for Range<N> where N: Ord{
79 type Coord = N;
80
81 #[inline(always)]
82 fn start(&self) -> &Self::Coord {
83 &self.start
84 }
85
86 #[inline(always)]
87 fn end(&self) -> &Self::Coord {
88 &self.end
89 }
90}
91
92#[derive(Debug)]
93pub struct NClist<T> where T: Interval {
94 intervals: Vec<T>,
95 contained: Vec<Option<(usize, usize)>>
96}
97
98struct SlicedNClist<'a, T> where T: 'a + Interval {
99 intervals: &'a [T],
100 contained: &'a [Option<(usize, usize)>],
101 stop_at: &'a T::Coord
102}
103
104pub struct Overlaps<'a, T> where T: 'a + Interval {
105 nclist: &'a NClist<T>,
106 range: &'a Range<T::Coord>,
107 current_pos: usize,
108 current_end: usize,
109 sublists: VecDeque<(usize, usize)>,
110}
111
112pub struct OrderedOverlaps<'a, T> where T: 'a + Interval {
113 nclist: &'a NClist<T>,
114 range: &'a Range<T::Coord>,
115 current: SlicedNClist<'a, T>,
116 queue: Vec<SlicedNClist<'a, T>>
117}
118
119impl<T> NClist<T> where T: Interval {
120 fn new() -> NClist<T> {
121 NClist { intervals: Vec::new(), contained: vec![Some((0,0))] }
122 }
123
124 pub fn from_vec(mut v: Vec<T>) -> Result<NClist<T>, &'static str> {
125 if v.iter().any(|e| e.end() <= e.start()) {
126 return Err("Cannot use intervals with zero or negative width");
127 }
128 v.sort_by(|a, b| a.start().cmp(b.start())
129 .then(a.end().cmp(b.end()).reverse()));
130
131 let mut list = NClist::new();
132 let mut sublists = VecDeque::from(vec![NClistBuilder { intervals: v, contained_pos: 0}]);
133
134 while !sublists.is_empty() {
135 build_nclist(&mut sublists, &mut list);
136 }
137 Ok(list)
138 }
139
140 pub fn count_overlaps(&self, r: &Range<T::Coord>) -> usize {
144 if r.end <= r.start {
145 return 0;
146 }
147 let mut count = 0;
148 let mut queue = VecDeque::new();
149 queue.push_back(self.contained[0].unwrap());
150 while let Some((start, end)) = queue.pop_front() {
151 self.slice(start, end, &r.start, &r.end)
152 .for_each(|(_, contained)| {
153 count += 1;
154 if let Some(subrange) = *contained {
155 queue.push_back(subrange);
156 }
157 });
158 }
159 count
160 }
161
162 pub fn overlaps<'a>(&'a self, r: &'a Range<T::Coord>) -> Overlaps<'a , T> {
166 let current_slice = self.contained[0].as_ref().unwrap();
167 let start = if r.end > r.start {
169 self.bin_search_end(current_slice.0, current_slice.1, &r.start)
170 } else {
171 current_slice.1
172 };
173
174 Overlaps { nclist: self, range: r, current_pos: start, current_end: current_slice.1, sublists: VecDeque::new() }
175 }
176
177 pub fn overlaps_ordered<'a>(&'a self, r: &'a Range<T::Coord>) -> OrderedOverlaps<'a , T> {
181 let &(mut start, end) = self.contained[0].as_ref().unwrap();
182 if r.end <= r.start {
183 start = end;
184 }
185 OrderedOverlaps { nclist: self, range: r, current: self.slice(start, end, &r.start, &r.end), queue: Vec::new() }
186 }
187
188 pub fn into_vec(self) -> Vec<T> {
191 self.into()
192 }
193
194 #[inline]
195 fn slice<'a>(&'a self, mut start: usize, end: usize, q: &T::Coord, q_end: &'a T::Coord) -> SlicedNClist<'a, T> {
196 start += match self.intervals[start..end].binary_search_by(|e| e.end().cmp(q))
197 {
198 Ok(n) => n + 1,
199 Err(n) => n
200 };
201 SlicedNClist { intervals: &self.intervals[start..end], contained: &self.contained[start+1..end+1], stop_at: q_end }
202 }
203
204 #[inline]
205 fn bin_search_end(&self, start: usize, end: usize, q: &T::Coord) -> usize {
206 match self.intervals[start..end].binary_search_by(|e| e.end().cmp(q)) {
207 Ok(n) => n + 1,
208 Err(n) => n
209 }
210 }
211}
212
213impl<'a, T> Iterator for SlicedNClist<'a, T> where T: Interval {
214 type Item = (&'a T, &'a Option<(usize, usize)>);
215 #[inline]
216 fn next(&mut self) -> Option<Self::Item> {
217 if let Some((i, ref mut intervals)) = self.intervals.split_first() {
218 if i.start() >= self.stop_at {
219 None
220 } else {
221 let (c, ref mut contained) = self.contained.split_first().unwrap();
222 std::mem::replace(&mut self.intervals, intervals);
223 std::mem::replace(&mut self.contained, contained);
224 Some((i, c))
225 }
226 } else {
227 None
228 }
229 }
230}
231
232impl<'a, T> Iterator for Overlaps<'a, T> where T: Interval {
233 type Item = &'a T;
234 #[inline]
235 fn next(&mut self) -> Option<Self::Item> {
236 let remaining = self.current_end - self.current_pos;
237
238 if remaining == 0 || *self.nclist.intervals[self.current_pos].start() >= self.range.end {
239 if let Some((mut new_start, new_end)) = self.sublists.pop_front() {
240 new_start += self.nclist.bin_search_end(new_start, new_end, &self.range.start);
241 self.current_pos = new_start;
242 self.current_end = new_end;
243 self.next()
244 } else {
245 None
246 }
247 } else {
248 let pos = self.current_pos;
249 self.current_pos += 1;
250 if let Some(next_sublist) = self.nclist.contained[self.current_pos] {
251 self.sublists.push_back(next_sublist);
252 }
253 Some(&self.nclist.intervals[pos])
254 }
255 }
256}
257
258impl<'a, T> Iterator for OrderedOverlaps<'a, T> where T: Interval {
259 type Item = &'a T;
260 #[inline]
261 fn next(&mut self) -> Option<Self::Item> {
262 if let Some((interval, contained)) = self.current.next() {
263 if let Some((start, end)) = *contained {
264 let mut ns = self.nclist.slice(start, end, &self.range.start, &self.range.end);
265 std::mem::swap(&mut self.current, &mut ns);
266 self.queue.push(ns);
267 }
268 Some(interval)
269 } else if let Some(sublist) = self.queue.pop() {
270 self.current = sublist;
271 self.next()
272 } else {
273 None
274 }
275 }
276}
277
278struct NClistBuilder<T> {
280 intervals: Vec<T>,
281 contained_pos: usize,
282}
283
284fn build_nclist<T: Interval>(sublists: &mut VecDeque<NClistBuilder<T>>, result: &mut NClist<T>) {
285 if let Some(sublist) = sublists.pop_front() {
286 let mut it = sublist.intervals.into_iter().peekable();
288
289 let sublist_start = result.intervals.len();
290 while let Some(e) = it.next() {
291 let interval_pos = result.intervals.len();
292 let contained: Vec<_> = it.peeking_take_while(|n| n.end() < e.end()).collect();
293 if !contained.is_empty() {
294 sublists.push_back(NClistBuilder {intervals: contained, contained_pos: interval_pos + 1});
295 }
296 result.intervals.push(e);
297 result.contained.push(None);
298 }
299
300 result.contained[sublist.contained_pos] = Some((sublist_start, result.intervals.len()));
302 }
303}
304
305impl<T> TryFrom<Vec<T>> for NClist<T> where T: Interval {
306 type Error = &'static str;
307 fn try_from(v: Vec<T>) -> Result<Self, Self::Error> {
308 NClist::from_vec(v)
309 }
310}
311
312impl<T> Into<Vec<T>> for NClist<T> where T: Interval {
315 fn into(self) -> Vec<T> {
316 self.intervals
317 }
318}
319
320#[cfg(test)]
321mod tests {
322 use super::*;
323
324 #[test]
331 fn test_binary_search_implementation_details() {
332 let b = [1, 1, 2, 2, 3, 3, 3];
333 assert_eq!(b.binary_search(&1), Ok(1));
334 assert_eq!(b.binary_search(&2), Ok(3));
335 assert_eq!(b.binary_search(&3), Ok(6));
336 let b = [1, 1, 1, 1, 1, 3, 3, 3, 3];
337 assert_eq!(b.binary_search(&1), Ok(4));
338 assert_eq!(b.binary_search(&3), Ok(8));
339 let b = [1, 1, 1, 1, 3, 3, 3, 3, 3];
340 assert_eq!(b.binary_search(&1), Ok(3));
341 assert_eq!(b.binary_search(&3), Ok(8));
342 }
343
344 #[test]
345 fn from_vec() {
346 let list: Vec<Range<u64>> = vec![(10..15), (10..20), (1..8)].into_iter().collect();
347 let nclist = NClist::from_vec(list).unwrap();
348
349 assert_eq!(nclist.intervals.len(), 3);
350 assert!(nclist.contained[0].is_some());
351 assert!(nclist.contained[1].is_none());
352 assert!(nclist.contained[2].is_some());
353 assert!(nclist.contained[3].is_none());
354
355 let list: Vec<Range<u64>> = Vec::new();
356 let nclist = NClist::from_vec(list).unwrap();
357 assert_eq!(nclist.intervals.len(), 0);
358 }
359
360 #[test]
361 fn interval_width() {
362 let list: Vec<Range<u64>> = vec![(5..20), (19..20), (7..7)].into_iter().collect();
363 assert!(NClist::from_vec(list).is_err());
364 let list: Vec<Range<u64>> = vec![(5..20), (20..19), (7..8)].into_iter().collect();
365 assert!(NClist::from_vec(list).is_err());
366 }
367
368 #[test]
369 fn illegal_width_queries() {
370 let list: Vec<Range<u64>> = vec![(5..20), (19..20), (7..8)].into_iter().collect();
371 let nclist = NClist::from_vec(list).unwrap();
372 assert_eq!(nclist.count_overlaps(&(7..7)), 0);
373 assert_eq!(nclist.count_overlaps(&(8..7)), 0);
374 assert_eq!(nclist.count_overlaps(&(19..19)), 0);
375 assert_eq!(nclist.overlaps(&(7..7)).count(), 0);
376 assert_eq!(nclist.overlaps(&(8..7)).count(), 0);
377 assert_eq!(nclist.overlaps(&(19..19)).count(), 0);
378 assert_eq!(nclist.overlaps_ordered(&(7..7)).count(), 0);
379 assert_eq!(nclist.overlaps_ordered(&(8..7)).count(), 0);
380 assert_eq!(nclist.overlaps_ordered(&(19..19)).count(), 0);
381 }
382
383 #[test]
384 fn count() {
385 let list: Vec<Range<u64>> = vec![(10..15), (10..20), (1..8)].into_iter().collect();
386 let nclist = NClist::from_vec(list).unwrap();
387
388 assert_eq!(nclist.intervals.len(), 3);
389 assert_eq!(nclist.count_overlaps(&(5..20)), 3);
390 assert_eq!(nclist.count_overlaps(&(14..18)), 2);
391 assert_eq!(nclist.count_overlaps(&(150..180)), 0);
392 assert_eq!(nclist.count_overlaps(&(10..10)), 0);
393 assert_eq!(nclist.count_overlaps(&(10..11)), 2);
394 assert_eq!(nclist.count_overlaps(&(9..10)), 0);
395 assert_eq!(nclist.count_overlaps(&(8..9)), 0);
396 assert_eq!(nclist.count_overlaps(&(8..10)), 0);
397 assert_eq!(nclist.count_overlaps(&(20..100)), 0);
398
399 let list: Vec<Range<u64>> = Vec::new();
400 let nclist = NClist::from_vec(list).unwrap();
401 assert_eq!(nclist.count_overlaps(&(100..200)), 0);
402
403 }
404 #[test]
405 fn overlaps() {
406 let list: Vec<Range<u64>> = vec![(10..15), (10..20), (1..8)].into_iter().collect();
407 let nclist = NClist::from_vec(list).unwrap();
408
409 assert_eq!(nclist.intervals.len(), 3);
410 assert_eq!(nclist.overlaps(&(5..20)).count(), 3);
411
412 let mut q = nclist.overlaps_ordered(&(5..20));
413 assert_eq!(q.next(), Some(&(1..8)));
414 assert_eq!(q.next(), Some(&(10..20)));
415 assert_eq!(q.next(), Some(&(10..15)));
416 assert_eq!(q.next(), None);
417
418 assert_eq!(nclist.overlaps(&(20..100)).count(), 0);
419 assert_eq!(nclist.overlaps(&(8..10)).count(), 0);
420 assert_eq!(nclist.overlaps(&(8..9)).count(), 0);
421 }
422
423 #[test]
424 fn duplicate_intervals() {
425 let list: Vec<Range<u64>> = vec![(10..15), (11..13), (10..20), (1..8), (11..13), (16..18)].into_iter().collect();
426 let nclist = NClist::from_vec(list).unwrap();
427 println!("{:?}", nclist);
428
429 assert_eq!(nclist.overlaps(&(5..20)).count(), 6);
430 assert_eq!(nclist.overlaps(&(11..13)).count(), 4);
431
432 let mut q = nclist.overlaps_ordered(&(11..17));
433 assert_eq!(q.next(), Some(&(10..20)));
434 assert_eq!(q.next(), Some(&(10..15)));
435 assert_eq!(q.next(), Some(&(11..13)));
436 assert_eq!(q.next(), Some(&(11..13)));
437 assert_eq!(q.next(), Some(&(16..18)));
438 assert_eq!(q.next(), None);
439
440 assert_eq!(nclist.overlaps(&(20..100)).count(), 0);
441 assert_eq!(nclist.overlaps(&(8..10)).count(), 0);
442 assert_eq!(nclist.overlaps(&(8..9)).count(), 0);
443 }
444}