Skip to main content

fast_pull/base/
merge.rs

1use crate::ProgressEntry;
2
3pub trait Merge {
4    fn merge_progress(&mut self, new: ProgressEntry);
5}
6
7impl Merge for Vec<ProgressEntry> {
8    fn merge_progress(&mut self, new: ProgressEntry) {
9        let i = self.partition_point(|x| x.end < new.start);
10        if i == self.len() {
11            self.push(new);
12            return;
13        }
14        if self[i].start <= new.start && self[i].end >= new.end {
15            return;
16        }
17        let mut current_merge = new;
18        let mut j = i;
19        while j < self.len() {
20            let entry = &self[j];
21            if entry.start > current_merge.end {
22                break;
23            }
24            current_merge.start = current_merge.start.min(entry.start);
25            current_merge.end = current_merge.end.max(entry.end);
26            j += 1;
27        }
28        if j > i {
29            self.drain(i..j);
30        }
31        self.insert(i, current_merge);
32    }
33}
34
35#[cfg(test)]
36mod tests {
37    use super::*;
38
39    #[test]
40    fn test_merge() {
41        #[allow(clippy::single_range_in_vec_init)]
42        let mut v = vec![1..5, 8..10];
43        v.merge_progress(5..10);
44        assert_eq!(v, vec![1..10]);
45        v.merge_progress(10..20);
46        assert_eq!(v, vec![1..20]);
47        v.merge_progress(30..40);
48        assert_eq!(v, vec![1..20, 30..40]);
49        v.merge_progress(21..40);
50        assert_eq!(v, vec![1..20, 21..40]);
51        v.merge_progress(19..21);
52        assert_eq!(v, vec![1..40]);
53        v.merge_progress(50..60);
54        assert_eq!(v, vec![1..40, 50..60]);
55        v.merge_progress(50..60);
56        assert_eq!(v, vec![1..40, 50..60]);
57        v.merge_progress(52..60);
58        assert_eq!(v, vec![1..40, 50..60]);
59        v.merge_progress(52..53);
60        assert_eq!(v, vec![1..40, 50..60]);
61        v.merge_progress(52..61);
62        assert_eq!(v, vec![1..40, 50..61]);
63        v.merge_progress(62..70);
64        assert_eq!(v, vec![1..40, 50..61, 62..70]);
65        v.merge_progress(40..62);
66        assert_eq!(v, vec![1..70]);
67        v.merge_progress(72..82);
68        assert_eq!(v, vec![1..70, 72..82]);
69        v.merge_progress(0..90);
70        assert_eq!(v, vec![0..90]);
71    }
72}