fast_pull/base/
merge_progress.rs1extern 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}