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 = if i == 0 {
21                false
22            } else {
23                self[i - 1].can_merge(&new)
24            };
25            let u2 = self[i].can_merge(&new);
26            if u1 && u2 {
27                self[i - 1].end = self[i].end;
28                self.remove(i);
29            } else if u1 {
30                self[i - 1].end = new.end;
31            } else if u2 {
32                self[i].start = new.start;
33            } else {
34                self.insert(i, new);
35            }
36        }
37    }
38}
39
40#[cfg(test)]
41mod tests {
42    use super::*;
43    use alloc::vec;
44
45    #[test]
46    fn test_merge_into_empty_vec() {
47        let mut v: Vec<ProgressEntry> = Vec::new();
48        v.merge_progress(10..20);
49        assert_eq!(v, vec![10..20]);
50    }
51
52    #[test]
53    fn test_append_non_overlapping() {
54        #[allow(clippy::single_range_in_vec_init)]
55        let mut v = vec![1..5];
56        v.merge_progress(6..10);
57        assert_eq!(v, vec![1..5, 6..10]);
58    }
59
60    #[test]
61    fn test_prepend_non_overlapping() {
62        #[allow(clippy::single_range_in_vec_init)]
63        let mut v = vec![6..10];
64        v.merge_progress(1..5);
65        assert_eq!(v, vec![1..5, 6..10]);
66    }
67
68    #[test]
69    fn test_merge_with_last() {
70        #[allow(clippy::single_range_in_vec_init)]
71        let mut v = vec![1..5];
72        v.merge_progress(5..10);
73        assert_eq!(v, vec![1..10]);
74    }
75
76    #[test]
77    fn test_insert_between_two() {
78        let mut v = vec![1..5, 10..15];
79        v.merge_progress(6..8);
80        assert_eq!(v, vec![1..5, 6..8, 10..15]);
81    }
82
83    #[test]
84    fn test_merge_adjacent() {
85        #[allow(clippy::single_range_in_vec_init)]
86        let mut v = vec![1..5];
87        v.merge_progress(5..10);
88        assert_eq!(v, vec![1..10]);
89    }
90}