fast_pull/base/
merge_progress.rs

1use crate::{Mergeable, ProgressEntry};
2
3pub trait MergeProgress {
4    fn merge_progress(&mut self, new: ProgressEntry);
5}
6
7impl MergeProgress for Vec<ProgressEntry> {
8    fn merge_progress(&mut self, new: ProgressEntry) {
9        let i = self.partition_point(|old| old.start < new.start);
10        if i == self.len() {
11            match self.last_mut() {
12                Some(last) if last.end == new.start => {
13                    last.end = new.end;
14                }
15                _ => self.push(new),
16            }
17        } else {
18            let u1 = if i == 0 {
19                false
20            } else {
21                self[i - 1].can_merge(&new)
22            };
23            let u2 = self[i].can_merge(&new);
24            if u1 && u2 {
25                self[i - 1].end = self[i].end;
26                self.remove(i);
27            } else if u1 {
28                self[i - 1].end = new.end;
29            } else if u2 {
30                self[i].start = new.start;
31            } else {
32                self.insert(i, new);
33            }
34        }
35    }
36}
37
38#[cfg(test)]
39mod tests {
40    use super::*;
41
42    #[test]
43    fn test_merge_into_empty_vec() {
44        let mut v: Vec<ProgressEntry> = Vec::new();
45        v.merge_progress(10..20);
46        assert_eq!(v, vec![10..20]);
47    }
48
49    #[test]
50    fn test_append_non_overlapping() {
51        #[allow(clippy::single_range_in_vec_init)]
52        let mut v = vec![1..5];
53        v.merge_progress(6..10);
54        assert_eq!(v, vec![1..5, 6..10]);
55    }
56
57    #[test]
58    fn test_prepend_non_overlapping() {
59        #[allow(clippy::single_range_in_vec_init)]
60        let mut v = vec![6..10];
61        v.merge_progress(1..5);
62        assert_eq!(v, vec![1..5, 6..10]);
63    }
64
65    #[test]
66    fn test_merge_with_last() {
67        #[allow(clippy::single_range_in_vec_init)]
68        let mut v = vec![1..5];
69        v.merge_progress(5..10);
70        assert_eq!(v, vec![1..10]);
71    }
72
73    #[test]
74    fn test_insert_between_two() {
75        let mut v = vec![1..5, 10..15];
76        v.merge_progress(6..8);
77        assert_eq!(v, vec![1..5, 6..8, 10..15]);
78    }
79
80    #[test]
81    fn test_merge_adjacent() {
82        #[allow(clippy::single_range_in_vec_init)]
83        let mut v = vec![1..5];
84        v.merge_progress(5..10);
85        assert_eq!(v, vec![1..10]);
86    }
87}