fast_pull/base/
merge_progress.rs

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