Skip to content

Commit

Permalink
Move find_first/last tests to a separate file
Browse files Browse the repository at this point in the history
  • Loading branch information
schuster committed Dec 31, 2016
1 parent efeee21 commit e2977b1
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ use super::internal::*;
use super::*;
use super::len::*;

#[cfg(test)]
mod test;

// The key optimization for find_first is that a consumer can stop its search if
// some consumer to its left already found a match (and similarly for consumers
// to the right for find_last). To make this work, all consumers need some
Expand Down Expand Up @@ -120,73 +123,6 @@ impl<'f, ITEM, FIND_OP> Consumer<ITEM> for FindConsumer<'f, FIND_OP>
}
}

#[test]
fn same_range_first_consumers_return_correct_answer() {
let find_op = |x: &i32| x % 2 == 0;
let first_found = AtomicUsize::new(usize::max_value());
let far_right_consumer = FindConsumer::new(&find_op, MatchPosition::Leftmost, &first_found);

// We save a consumer that will be far to the right of the main consumer (and therefore not
// sharing an index range with that consumer) for fullness testing
let consumer = far_right_consumer.split_off();

// split until we have an indivisible range
let bits_in_usize = usize::min_value().count_zeros();
for i in 0..bits_in_usize {
consumer.split_off();
}

let reducer = consumer.to_reducer();
// the left and right folders should now have the same range, having
// exhausted the resolution of usize
let left_folder = consumer.split_off().into_folder();
let right_folder = consumer.into_folder();

let left_folder = left_folder.consume(0).consume(1);
assert_eq!(left_folder.boundary, right_folder.boundary);
// expect not full even though a better match has been found because the
// ranges are the same
assert!(!right_folder.full());
assert!(far_right_consumer.full());
let right_folder = right_folder.consume(2).consume(3);
assert_eq!(reducer.reduce(left_folder.complete(), right_folder.complete()),
Some(0));
}

#[test]
fn same_range_last_consumers_return_correct_answer() {
let find_op = |x: &i32| x % 2 == 0;
let last_found = AtomicUsize::new(0);
let consumer = FindConsumer::new(&find_op, MatchPosition::Rightmost, &last_found);

// We save a consumer that will be far to the left of the main consumer (and therefore not
// sharing an index range with that consumer) for fullness testing
let far_left_consumer = consumer.split_off();

// split until we have an indivisible range
let bits_in_usize = usize::min_value().count_zeros();
for i in 0..bits_in_usize {
consumer.split_off();
}

let reducer = consumer.to_reducer();
// due to the exact calculation in split_off, the very last consumer has a
// range of width 2, so we use the second-to-last consumer instead to get
// the same boundary on both folders
let consumer = consumer.split_off();
let left_folder = consumer.split_off().into_folder();
let right_folder = consumer.into_folder();
let right_folder = right_folder.consume(2).consume(3);
assert_eq!(left_folder.boundary, right_folder.boundary);
// expect not full even though a better match has been found because the
// ranges are the same
assert!(!left_folder.full());
assert!(far_left_consumer.full());
let left_folder = left_folder.consume(0).consume(1);
assert_eq!(reducer.reduce(left_folder.complete(), right_folder.complete()),
Some(2));
}

impl<'f, ITEM, FIND_OP> UnindexedConsumer<ITEM> for FindConsumer<'f, FIND_OP>
where ITEM: Send,
FIND_OP: Fn(&ITEM) -> bool + Sync
Expand Down
69 changes: 69 additions & 0 deletions src/par_iter/find_first_last/test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use std::sync::atomic::AtomicUsize;
use super::*;

#[test]
fn same_range_first_consumers_return_correct_answer() {
let find_op = |x: &i32| x % 2 == 0;
let first_found = AtomicUsize::new(usize::max_value());
let far_right_consumer = FindConsumer::new(&find_op, MatchPosition::Leftmost, &first_found);

// We save a consumer that will be far to the right of the main consumer (and therefore not
// sharing an index range with that consumer) for fullness testing
let consumer = far_right_consumer.split_off();

// split until we have an indivisible range
let bits_in_usize = usize::min_value().count_zeros();
for i in 0..bits_in_usize {
consumer.split_off();
}

let reducer = consumer.to_reducer();
// the left and right folders should now have the same range, having
// exhausted the resolution of usize
let left_folder = consumer.split_off().into_folder();
let right_folder = consumer.into_folder();

let left_folder = left_folder.consume(0).consume(1);
assert_eq!(left_folder.boundary, right_folder.boundary);
// expect not full even though a better match has been found because the
// ranges are the same
assert!(!right_folder.full());
assert!(far_right_consumer.full());
let right_folder = right_folder.consume(2).consume(3);
assert_eq!(reducer.reduce(left_folder.complete(), right_folder.complete()),
Some(0));
}

#[test]
fn same_range_last_consumers_return_correct_answer() {
let find_op = |x: &i32| x % 2 == 0;
let last_found = AtomicUsize::new(0);
let consumer = FindConsumer::new(&find_op, MatchPosition::Rightmost, &last_found);

// We save a consumer that will be far to the left of the main consumer (and therefore not
// sharing an index range with that consumer) for fullness testing
let far_left_consumer = consumer.split_off();

// split until we have an indivisible range
let bits_in_usize = usize::min_value().count_zeros();
for i in 0..bits_in_usize {
consumer.split_off();
}

let reducer = consumer.to_reducer();
// due to the exact calculation in split_off, the very last consumer has a
// range of width 2, so we use the second-to-last consumer instead to get
// the same boundary on both folders
let consumer = consumer.split_off();
let left_folder = consumer.split_off().into_folder();
let right_folder = consumer.into_folder();
let right_folder = right_folder.consume(2).consume(3);
assert_eq!(left_folder.boundary, right_folder.boundary);
// expect not full even though a better match has been found because the
// ranges are the same
assert!(!left_folder.full());
assert!(far_left_consumer.full());
let left_folder = left_folder.consume(0).consume(1);
assert_eq!(reducer.reduce(left_folder.complete(), right_folder.complete()),
Some(2));
}

0 comments on commit e2977b1

Please sign in to comment.