Skip to content

Commit 3ab67eb

Browse files
committed
FEAT: Add ParalleIterator ParallelSplits
This iterator is for internal use; it produces the splits of a Zip (it splits the Zip the same way as the regular parallel iterator for Zip, but here the whole Zip is the produced item of the iterator.) This is helpful as a building block for other operations.
1 parent 84295c4 commit 3ab67eb

File tree

1 file changed

+52
-1
lines changed

1 file changed

+52
-1
lines changed

src/parallel/par.rs

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use crate::iter::AxisIter;
1515
use crate::iter::AxisIterMut;
1616
use crate::Dimension;
1717
use crate::{ArrayView, ArrayViewMut};
18+
use crate::split_at::SplitPreference;
1819

1920
/// Parallel iterator wrapper.
2021
#[derive(Copy, Clone, Debug)]
@@ -250,7 +251,7 @@ macro_rules! zip_impl {
250251
type Item = ($($p::Item ,)*);
251252

252253
fn split(self) -> (Self, Option<Self>) {
253-
if self.0.size() <= 1 {
254+
if !self.0.can_split() {
254255
return (self, None)
255256
}
256257
let (a, b) = self.0.split();
@@ -282,3 +283,53 @@ zip_impl! {
282283
[P1 P2 P3 P4 P5],
283284
[P1 P2 P3 P4 P5 P6],
284285
}
286+
287+
/// A parallel iterator (unindexed) that produces the splits of the array
288+
/// or producer `P`.
289+
pub(crate) struct ParallelSplits<P> {
290+
pub(crate) iter: P,
291+
pub(crate) min_size: usize,
292+
}
293+
294+
impl<P> ParallelIterator for ParallelSplits<P>
295+
where P: SplitPreference + Send,
296+
{
297+
type Item = P;
298+
299+
fn drive_unindexed<C>(self, consumer: C) -> C::Result
300+
where C: UnindexedConsumer<Self::Item>
301+
{
302+
bridge_unindexed(self, consumer)
303+
}
304+
305+
fn opt_len(&self) -> Option<usize> {
306+
None
307+
}
308+
}
309+
310+
impl<P> UnindexedProducer for ParallelSplits<P>
311+
where P: SplitPreference + Send,
312+
{
313+
type Item = P;
314+
315+
fn split(self) -> (Self, Option<Self>) {
316+
if self.iter.size() <= self.min_size || !self.iter.can_split() {
317+
return (self, None)
318+
}
319+
let (a, b) = self.iter.split();
320+
(ParallelSplits {
321+
iter: a,
322+
min_size: self.min_size,
323+
},
324+
Some(ParallelSplits {
325+
iter: b,
326+
min_size: self.min_size,
327+
}))
328+
}
329+
330+
fn fold_with<Fold>(self, folder: Fold) -> Fold
331+
where Fold: Folder<Self::Item>,
332+
{
333+
folder.consume(self.iter)
334+
}
335+
}

0 commit comments

Comments
 (0)