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 = 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}