1use alloc::vec::Vec;
2use core::cmp::Ordering;
3use itertools::Itertools;
4
5pub(crate) fn kway_merge_sorted<'a, K, V>(
10 slices: impl IntoIterator<Item = &'a [(K, V)]>,
11) -> Vec<(K, V)>
12where
13 K: Ord + Clone + 'a,
14 V: Clone + 'a,
15{
16 slices
17 .into_iter()
18 .filter(|s| !s.is_empty())
19 .enumerate()
20 .map(|(i, s)| s.iter().map(move |(k, v)| (i, k, v)))
22 .kmerge_by(|(i1, k1, _), (i2, k2, _)| (k1, i1) < (k2, i2))
23 .dedup_by(|(_, k1, _), (_, k2, _)| *k1 == *k2)
24 .map(|(_, k, v)| (k.clone(), v.clone()))
26 .collect()
27}
28
29pub(crate) fn extend_sorted_vec<K, V>(target: &mut Vec<(K, V)>, other: &[(K, V)])
32where
33 K: Clone + Ord,
34 V: Clone,
35{
36 if other.is_empty() {
37 return;
38 }
39
40 if target.is_empty() {
41 target.extend_from_slice(other);
42 return;
43 }
44
45 if target.last().map(|(k, _)| k) < other.first().map(|(k, _)| k) {
47 target.extend_from_slice(other);
48 return;
49 }
50
51 let left = core::mem::take(target);
53 let mut out = Vec::with_capacity(left.len() + other.len());
54
55 let mut a = left.into_iter().peekable();
56 let mut b = other.iter().peekable();
57
58 while let (Some(aa), Some(bb)) = (a.peek(), b.peek()) {
59 match aa.0.cmp(&bb.0) {
60 Ordering::Less => {
61 out.push(a.next().unwrap());
62 }
63 Ordering::Greater => {
64 out.push(b.next().unwrap().clone());
65 }
66 Ordering::Equal => {
67 let (k, _) = a.next().unwrap();
69 out.push((k, b.next().unwrap().1.clone()));
70 }
71 }
72 }
73
74 out.extend(a);
76 out.extend(b.cloned());
77
78 *target = out;
79}
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84
85 #[test]
86 fn test_extend_sorted_vec() {
87 let mut target = vec![(1, "a"), (3, "c")];
88 let other = vec![(2, "b"), (3, "c_new")];
89 extend_sorted_vec(&mut target, &other);
90 assert_eq!(target, vec![(1, "a"), (2, "b"), (3, "c_new")]);
91 }
92
93 #[test]
94 fn test_extend_sorted_vec_empty_target() {
95 let mut target: Vec<(i32, &str)> = vec![];
96 let other = vec![(1, "a"), (2, "b")];
97 extend_sorted_vec(&mut target, &other);
98 assert_eq!(target, vec![(1, "a"), (2, "b")]);
99 }
100
101 #[test]
102 fn test_extend_sorted_vec_empty_other() {
103 let mut target = vec![(1, "a"), (2, "b")];
104 let other: Vec<(i32, &str)> = vec![];
105 extend_sorted_vec(&mut target, &other);
106 assert_eq!(target, vec![(1, "a"), (2, "b")]);
107 }
108
109 #[test]
110 fn test_extend_sorted_vec_all_duplicates() {
111 let mut target = vec![(1, "old1"), (2, "old2"), (3, "old3")];
112 let other = vec![(1, "new1"), (2, "new2"), (3, "new3")];
113 extend_sorted_vec(&mut target, &other);
114 assert_eq!(target, vec![(1, "new1"), (2, "new2"), (3, "new3")]);
116 }
117
118 #[test]
119 fn test_extend_sorted_vec_interleaved() {
120 let mut target = vec![(1, "a"), (3, "c"), (5, "e")];
121 let other = vec![(2, "b"), (4, "d"), (6, "f")];
122 extend_sorted_vec(&mut target, &other);
123 assert_eq!(target, vec![(1, "a"), (2, "b"), (3, "c"), (4, "d"), (5, "e"), (6, "f")]);
124 }
125
126 #[test]
127 fn test_extend_sorted_vec_other_all_smaller() {
128 let mut target = vec![(5, "e"), (6, "f")];
129 let other = vec![(1, "a"), (2, "b")];
130 extend_sorted_vec(&mut target, &other);
131 assert_eq!(target, vec![(1, "a"), (2, "b"), (5, "e"), (6, "f")]);
132 }
133
134 #[test]
135 fn test_extend_sorted_vec_other_all_larger() {
136 let mut target = vec![(1, "a"), (2, "b")];
137 let other = vec![(5, "e"), (6, "f")];
138 extend_sorted_vec(&mut target, &other);
139 assert_eq!(target, vec![(1, "a"), (2, "b"), (5, "e"), (6, "f")]);
140 }
141
142 #[test]
143 fn test_kway_merge_sorted_basic() {
144 let slice1 = vec![(1, "a1"), (3, "c1")];
145 let slice2 = vec![(2, "b2"), (3, "c2")];
146 let slice3 = vec![(1, "a3"), (4, "d3")];
147
148 let result = kway_merge_sorted([slice1.as_slice(), slice2.as_slice(), slice3.as_slice()]);
149 assert_eq!(result, vec![(1, "a1"), (2, "b2"), (3, "c1"), (4, "d3")]);
151 }
152
153 #[test]
154 fn test_kway_merge_sorted_empty_slices() {
155 let slice1: Vec<(i32, &str)> = vec![];
156 let slice2 = vec![(1, "a")];
157 let slice3: Vec<(i32, &str)> = vec![];
158
159 let result = kway_merge_sorted([slice1.as_slice(), slice2.as_slice(), slice3.as_slice()]);
160 assert_eq!(result, vec![(1, "a")]);
161 }
162
163 #[test]
164 fn test_kway_merge_sorted_all_same_key() {
165 let slice1 = vec![(5, "first")];
166 let slice2 = vec![(5, "middle")];
167 let slice3 = vec![(5, "last")];
168
169 let result = kway_merge_sorted([slice1.as_slice(), slice2.as_slice(), slice3.as_slice()]);
170 assert_eq!(result, vec![(5, "first")]);
172 }
173
174 #[test]
175 fn test_kway_merge_sorted_single_slice() {
176 let slice = vec![(1, "a"), (2, "b"), (3, "c")];
177 let result = kway_merge_sorted([slice.as_slice()]);
178 assert_eq!(result, vec![(1, "a"), (2, "b"), (3, "c")]);
179 }
180
181 #[test]
182 fn test_kway_merge_sorted_no_slices() {
183 let result: Vec<(i32, &str)> = kway_merge_sorted(Vec::<&[(i32, &str)]>::new());
184 assert!(result.is_empty());
185 }
186}