Skip to content

Commit abd942e

Browse files
bors[bot]seanchen1991cuviper
committed
627: Add `find_map` with `any`, `first`, and `last` variants r=cuviper a=seanchen1991 PR opened in response to rayon-rs#607. 633: Update dev and demo dependencies r=cuviper a=cuviper - `cgmath 0.17` - `glium 0.23` - `rand 0.6` Co-authored-by: Sean <[email protected]> Co-authored-by: Josh Stone <[email protected]>
3 parents 502c929 + 8fbb588 + d2609d8 commit abd942e

File tree

16 files changed

+175
-22
lines changed

16 files changed

+175
-22
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ default-features = false
3030
[dev-dependencies]
3131
docopt = "1"
3232
lazy_static = "1"
33-
rand = "0.5"
33+
rand = "0.6"
34+
rand_xorshift = "0.1"
3435
serde = "1"
3536
serde_derive = "1"

rayon-core/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ version = "0.2.0"
2828
version = "0.3.0"
2929

3030
[dev-dependencies]
31-
rand = "0.5"
31+
rand = "0.6"
32+
rand_xorshift = "0.1"
3233

3334
[[test]]
3435
name = "stack_overflow_crash"

rayon-core/src/join/test.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
33
use join::*;
44
use rand::distributions::Standard;
5-
use rand::{Rng, SeedableRng, XorShiftRng};
5+
use rand::{Rng, SeedableRng};
6+
use rand_xorshift::XorShiftRng;
67
use unwind;
78
use ThreadPoolBuilder;
89

rayon-core/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ extern crate num_cpus;
4040

4141
#[cfg(test)]
4242
extern crate rand;
43+
#[cfg(test)]
44+
extern crate rand_xorshift;
4345

4446
#[macro_use]
4547
mod log;

rayon-core/src/scope/test.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
use rand::{Rng, SeedableRng, XorShiftRng};
1+
use rand::{Rng, SeedableRng};
2+
use rand_xorshift::XorShiftRng;
23
use std::cmp;
34
use std::iter::once;
45
use std::sync::atomic::{AtomicUsize, Ordering};

rayon-demo/Cargo.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@ publish = false
66

77
[dependencies]
88
rayon = { path = "../" }
9-
cgmath = "0.16"
9+
cgmath = "0.17"
1010
docopt = "1"
1111
fixedbitset = "0.1.5"
12-
glium = "0.21"
12+
glium = "0.23"
1313
lazy_static = "1"
1414
odds = "0.3"
15-
rand = "0.5"
15+
rand = "0.6"
16+
rand_xorshift = "0.1"
1617
regex = "1"
1718
serde = "1"
1819
serde_derive = "1"

rayon-demo/src/main.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ extern crate libc; // life
4848
extern crate num;
4949
extern crate odds; // sieve
5050
extern crate rand; // nbody
51+
extern crate rand_xorshift; // nbody
5152
extern crate time; // nbody, sieve // factorial
5253
#[macro_use]
5354
extern crate lazy_static; // find
@@ -109,8 +110,9 @@ fn main() {
109110
}
110111
}
111112

112-
fn seeded_rng() -> rand::XorShiftRng {
113-
use rand::{SeedableRng, XorShiftRng};
113+
fn seeded_rng() -> rand_xorshift::XorShiftRng {
114+
use rand::SeedableRng;
115+
use rand_xorshift::XorShiftRng;
114116
let mut seed = <XorShiftRng as SeedableRng>::Seed::default();
115117
(0..).zip(seed.as_mut()).for_each(|(i, x)| *x = i);
116118
XorShiftRng::from_seed(seed)

rayon-demo/src/nbody/visualize.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ implement_vertex!(Instance, color, world_position);
8080
pub fn visualize_benchmarks(num_bodies: usize, mut mode: ExecutionMode) {
8181
let mut events_loop = EventsLoop::new();
8282
let window = WindowBuilder::new()
83-
.with_dimensions(800, 600)
83+
.with_dimensions((800, 600).into())
8484
.with_title("nbody demo".to_string());
8585
let context = ContextBuilder::new().with_depth_buffer(24);
8686
let display = Display::new(window, context, &events_loop).unwrap();
@@ -191,7 +191,7 @@ pub fn visualize_benchmarks(num_bodies: usize, mut mode: ExecutionMode) {
191191
events_loop.poll_events(|event| {
192192
if let Event::WindowEvent { event, .. } = event {
193193
match event {
194-
WindowEvent::Closed => done = true,
194+
WindowEvent::CloseRequested => done = true,
195195
WindowEvent::KeyboardInput { input, .. } => {
196196
if let ElementState::Pressed = input.state {
197197
match input.virtual_keycode {

rayon-demo/src/str_split.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
//! Some microbenchmarks for splitting strings
22
3-
use rand::Rng;
3+
use rand::seq::SliceRandom;
44
use rayon::prelude::*;
55
use test::Bencher;
66

77
lazy_static! {
88
static ref HAYSTACK: String = {
99
let mut rng = ::seeded_rng();
1010
let mut bytes: Vec<u8> = "abcdefg ".bytes().cycle().take(1_000_000).collect();
11-
rng.shuffle(&mut bytes);
11+
bytes.shuffle(&mut rng);
1212
String::from_utf8(bytes).unwrap()
1313
};
1414
static ref COUNT: usize = { HAYSTACK.split(' ').count() };

src/iter/mod.rs

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1504,7 +1504,7 @@ pub trait ParallelIterator: Sized + Send {
15041504
/// just want the first match that discovered anywhere in the iterator,
15051505
/// `find_any` is a better choice.
15061506
///
1507-
/// # Exmaples
1507+
/// # Examples
15081508
///
15091509
/// ```
15101510
/// use rayon::prelude::*;
@@ -1551,6 +1551,99 @@ pub trait ParallelIterator: Sized + Send {
15511551
find_first_last::find_last(self, predicate)
15521552
}
15531553

1554+
/// Applies the given predicate to the items in the parallel iterator
1555+
/// and returns **any** non-None result of the map operation.
1556+
///
1557+
/// Once a non-None value is produced from the map operation, we will
1558+
/// attempt to stop processing the rest of the items in the iterator
1559+
/// as soon as possible.
1560+
///
1561+
/// Note that this method only returns **some** item in the parallel
1562+
/// iterator that is not None from the map predicate. The item returned
1563+
/// may not be the **first** non-None value produced in the parallel
1564+
/// sequence, since the entire sequence is mapped over in parallel.
1565+
///
1566+
/// # Examples
1567+
///
1568+
/// ```
1569+
/// use rayon::prelude::*;
1570+
///
1571+
/// let c = ["lol", "NaN", "5", "5"];
1572+
///
1573+
/// let first_number = c.par_iter().find_map_first(|s| s.parse().ok());
1574+
///
1575+
/// assert_eq!(first_number, Some(5));
1576+
/// ```
1577+
fn find_map_any<P, R>(self, predicate: P) -> Option<R>
1578+
where
1579+
P: Fn(Self::Item) -> Option<R> + Sync + Send,
1580+
R: Send,
1581+
{
1582+
self.filter_map(predicate).find_any(|_| true)
1583+
}
1584+
1585+
/// Applies the given predicate to the items in the parallel iterator and
1586+
/// returns the sequentially **first** non-None result of the map operation.
1587+
///
1588+
/// Once a non-None value is produced from the map operation, all attempts
1589+
/// to the right of the match will be stopped, while attempts to the left
1590+
/// must continue in case an earlier match is found.
1591+
///
1592+
/// Note that not all parallel iterators have a useful order, much like
1593+
/// sequential `HashMap` iteration, so "first" may be nebulous. If you
1594+
/// just want the first non-None value discovered anywhere in the iterator,
1595+
/// `find_map_any` is a better choice.
1596+
///
1597+
/// # Examples
1598+
///
1599+
/// ```
1600+
/// use rayon::prelude::*;
1601+
///
1602+
/// let c = ["lol", "NaN", "2", "5"];
1603+
///
1604+
/// let first_number = c.par_iter().find_map_first(|s| s.parse().ok());
1605+
///
1606+
/// assert_eq!(first_number, Some(2));
1607+
/// ```
1608+
fn find_map_first<P, R>(self, predicate: P) -> Option<R>
1609+
where
1610+
P: Fn(Self::Item) -> Option<R> + Sync + Send,
1611+
R: Send,
1612+
{
1613+
self.filter_map(predicate).find_first(|_| true)
1614+
}
1615+
1616+
/// Applies the given predicate to the items in the parallel iterator and
1617+
/// returns the sequentially **last** non-None result of the map operation.
1618+
///
1619+
/// Once a non-None value is produced from the map operation, all attempts
1620+
/// to the left of the match will be stopped, while attempts to the right
1621+
/// must continue in case a later match is found.
1622+
///
1623+
/// Note that not all parallel iterators have a useful order, much like
1624+
/// sequential `HashMap` iteration, so "first" may be nebulous. If you
1625+
/// just want the first non-None value discovered anywhere in the iterator,
1626+
/// `find_map_any` is a better choice.
1627+
///
1628+
/// # Examples
1629+
///
1630+
/// ```
1631+
/// use rayon::prelude::*;
1632+
///
1633+
/// let c = ["lol", "NaN", "2", "5"];
1634+
///
1635+
/// let first_number = c.par_iter().find_map_last(|s| s.parse().ok());
1636+
///
1637+
/// assert_eq!(first_number, Some(5));
1638+
/// ```
1639+
fn find_map_last<P, R>(self, predicate: P) -> Option<R>
1640+
where
1641+
P: Fn(Self::Item) -> Option<R> + Sync + Send,
1642+
R: Send,
1643+
{
1644+
self.filter_map(predicate).find_last(|_| true)
1645+
}
1646+
15541647
#[doc(hidden)]
15551648
#[deprecated(note = "parallel `find` does not search in order -- use `find_any`, \\
15561649
`find_first`, or `find_last`")]

0 commit comments

Comments
 (0)