Skip to content

Commit

Permalink
Merge pull request #184 from bluss/fold-using
Browse files Browse the repository at this point in the history
Add method fold_with to Producer and UnindexedProducer
  • Loading branch information
nikomatsakis committed Dec 21, 2016
2 parents ee5799c + 31449c8 commit a2f2cc2
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 16 deletions.
11 changes: 11 additions & 0 deletions src/par_iter/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,17 @@ impl<A, B> Producer for ChainProducer<A, B>
ChainProducer::new(0, a_right, b_right))
}
}

fn fold_with<F>(self, mut folder: F) -> F
where F: Folder<A::Item>,
{
folder = self.a.fold_with(folder);
if folder.full() {
folder
} else {
self.b.fold_with(folder)
}
}
}

impl<A, B> IntoIterator for ChainProducer<A, B>
Expand Down
50 changes: 34 additions & 16 deletions src/par_iter/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,22 @@ pub trait Producer: IntoIterator + Send + Sized {
/// Split into two producers; one produces items `0..index`, the
/// other `index..N`. Index must be less than `N`.
fn split_at(self, index: usize) -> (Self, Self);

/// Iterate the producer, feeding each element to `folder`, and
/// stop when the folder is full (or all elements have been consumed).
///
/// The provided implementation is sufficient for most iterables.
fn fold_with<F>(self, mut folder: F) -> F
where F: Folder<Self::Item>,
{
for item in self {
folder = folder.consume(item);
if folder.full() {
break;
}
}
folder
}
}

/// A consumer which consumes items that are fed to it.
Expand Down Expand Up @@ -95,6 +111,22 @@ pub trait UnindexedConsumer<ITEM>: Consumer<ITEM> {
pub trait UnindexedProducer: IntoIterator + Send + Sized {
fn can_split(&self) -> bool;
fn split(self) -> (Self, Self);

/// Iterate the producer, feeding each element to `folder`, and
/// stop when the folder is full (or all elements have been consumed).
///
/// The provided implementation is sufficient for most iterables.
fn fold_with<F>(self, mut folder: F) -> F
where F: Folder<Self::Item>,
{
for item in self {
folder = folder.consume(item);
if folder.full() {
break;
}
}
folder
}
}

/// A splitter controls the policy for splitting into smaller work items.
Expand Down Expand Up @@ -207,14 +239,7 @@ pub fn bridge_producer_consumer<P, C>(len: usize, mut producer: P, mut consumer:
|| helper(len - mid, splitter, right_producer, right_consumer));
reducer.reduce(left_result, right_result)
} else {
let mut folder = consumer.into_folder();
for item in producer {
folder = folder.consume(item);
if folder.full() {
break;
}
}
folder.complete()
producer.fold_with(consumer.into_folder()).complete()
}
}
}
Expand Down Expand Up @@ -245,13 +270,6 @@ fn bridge_unindexed_producer_consumer<P, C>(mut splitter: Splitter,
|| bridge_unindexed_producer_consumer(splitter, right_producer, right_consumer));
reducer.reduce(left_result, right_result)
} else {
let mut folder = consumer.into_folder();
for item in producer {
folder = folder.consume(item);
if folder.full() {
break;
}
}
folder.complete()
producer.fold_with(consumer.into_folder()).complete()
}
}

0 comments on commit a2f2cc2

Please sign in to comment.