moirai_iter/parallel/adapters/
pair.rs1use super::super::{Consumer, ParallelIterator, VecParIter};
2
3fn interleave_all<T>(left: Vec<T>, right: Vec<T>) -> Vec<T> {
4 let len = left.len().checked_add(right.len()).expect("overflow");
5 let paired_len = left.len().min(right.len());
6 let mut left = left.into_iter();
7 let mut right = right.into_iter();
8 let mut output = Vec::with_capacity(len);
9
10 for _ in 0..paired_len {
11 output.push(left.next().expect("paired length is bounded by left input"));
12 output.push(
13 right
14 .next()
15 .expect("paired length is bounded by right input"),
16 );
17 }
18 output.extend(left);
19 output.extend(right);
20 output
21}
22
23fn interleave_shortest<T>(mut left: Vec<T>, mut right: Vec<T>) -> Vec<T> {
24 let left_take = if left.len() <= right.len() {
25 left.len()
26 } else {
27 right.len() + 1
28 };
29 let right_take = right.len().min(left.len());
30
31 let output_len = left_take.checked_add(right_take).expect("overflow");
32 left.truncate(left_take);
33 right.truncate(right_take);
34
35 let mut left = left.into_iter();
36 let mut right = right.into_iter();
37 let mut output = Vec::with_capacity(output_len);
38 for _ in 0..right_take {
39 output.push(left.next().expect("take count is bounded by left input"));
40 output.push(right.next().expect("take count is bounded by right input"));
41 }
42 output.extend(left);
43 output
44}
45
46pub struct Zip<I, J> {
48 left: I,
49 right: J,
50}
51
52impl<I, J> Zip<I, J> {
53 pub(in crate::parallel) fn new(left: I, right: J) -> Self {
54 Self { left, right }
55 }
56}
57
58impl<I, J> ParallelIterator for Zip<I, J>
59where
60 I: ParallelIterator,
61 J: ParallelIterator,
62 I::Item: Sync + 'static,
63 J::Item: Sync + 'static,
64{
65 type Item = (I::Item, J::Item);
66
67 fn seq_items(self) -> Vec<Self::Item> {
68 self.left
69 .seq_items()
70 .into_iter()
71 .zip(self.right.seq_items())
72 .collect()
73 }
74
75 fn drive<C, R>(self, consumer: C) -> R
87 where
88 C: Consumer<Self::Item, Result = R> + Send + Sync,
89 R: Send,
90 {
91 consumer.consume(VecParIter::new(self.seq_items()))
92 }
93}
94
95pub struct ZipEq<I, J> {
97 pub(in crate::parallel) left: I,
98 pub(in crate::parallel) right: J,
99}
100
101impl<I, J> ZipEq<I, J> {
102 pub(in crate::parallel) fn new(left: I, right: J) -> Self {
103 Self { left, right }
104 }
105}
106
107impl<I, J> ParallelIterator for ZipEq<I, J>
108where
109 I: ParallelIterator,
110 J: ParallelIterator,
111 I::Item: Sync + 'static,
112 J::Item: Sync + 'static,
113{
114 type Item = (I::Item, J::Item);
115
116 fn seq_items(self) -> Vec<Self::Item> {
117 let left = self.left.seq_items();
118 let right = self.right.seq_items();
119 assert_eq!(
120 left.len(),
121 right.len(),
122 "zip_eq requires equal input lengths"
123 );
124 left.into_iter().zip(right).collect()
125 }
126
127 fn drive<C, R>(self, consumer: C) -> R
131 where
132 C: Consumer<Self::Item, Result = R> + Send + Sync,
133 R: Send,
134 {
135 consumer.consume(VecParIter::new(self.seq_items()))
136 }
137}
138
139pub struct Interleave<I, J> {
141 pub(in crate::parallel) left: I,
142 pub(in crate::parallel) right: J,
143}
144
145impl<I, J> Interleave<I, J> {
146 pub(in crate::parallel) fn new(left: I, right: J) -> Self {
147 Self { left, right }
148 }
149}
150
151impl<I, J> ParallelIterator for Interleave<I, J>
152where
153 I: ParallelIterator,
154 J: ParallelIterator<Item = I::Item>,
155 I::Item: Sync + 'static,
156{
157 type Item = I::Item;
158
159 fn seq_items(self) -> Vec<Self::Item> {
160 interleave_all(self.left.seq_items(), self.right.seq_items())
161 }
162
163 fn drive<C, R>(self, consumer: C) -> R
167 where
168 C: Consumer<Self::Item, Result = R> + Send + Sync,
169 R: Send,
170 {
171 consumer.consume(VecParIter::new(self.seq_items()))
172 }
173}
174
175pub struct InterleaveShortest<I, J> {
177 pub(in crate::parallel) left: I,
178 pub(in crate::parallel) right: J,
179}
180
181impl<I, J> InterleaveShortest<I, J> {
182 pub(in crate::parallel) fn new(left: I, right: J) -> Self {
183 Self { left, right }
184 }
185}
186
187impl<I, J> ParallelIterator for InterleaveShortest<I, J>
188where
189 I: ParallelIterator,
190 J: ParallelIterator<Item = I::Item>,
191 I::Item: Sync + 'static,
192{
193 type Item = I::Item;
194
195 fn seq_items(self) -> Vec<Self::Item> {
196 interleave_shortest(self.left.seq_items(), self.right.seq_items())
197 }
198
199 fn drive<C, R>(self, consumer: C) -> R
203 where
204 C: Consumer<Self::Item, Result = R> + Send + Sync,
205 R: Send,
206 {
207 consumer.consume(VecParIter::new(self.seq_items()))
208 }
209}