@Test public void MultiReaderUnifiedSet_hasNext() { MultiReaderUnifiedSet<Integer> iterable = this.newWith(3, 2, 1); iterable.withReadLockAndDelegate(delegate -> assertTrue(delegate.iterator().hasNext())); MultiReaderUnifiedSet<?> emptyIterable = this.newWith(); emptyIterable.withReadLockAndDelegate(delegate -> assertFalse(delegate.iterator().hasNext())); }
@Test public void MultiReaderUnifiedSet_next_throws_on_empty() { MultiReaderUnifiedSet<Object> iterable = this.newWith(); assertThrows( NoSuchElementException.class, () -> iterable.withReadLockAndDelegate(delegate -> delegate.iterator().next())); }
private static void assertUnifiedSetClear(int shift) { MultiReaderUnifiedSet<CollidingInt> set = MultiReaderUnifiedSet.newSet(); int size = 100000; for (int i = 0; i < size; i++) { Assert.assertTrue(set.add(new CollidingInt(i, shift))); } set.clear(); Verify.assertEmpty(set); for (int i = 0; i < size; i++) { Verify.assertNotContains(new CollidingInt(i, shift), set); } }
// TODO Is it possible to pull with withReadLockAndDelegate to MultiReaderMutableCollection? // TODO Is it possible to pull with withWriteLockAndDelegate to MultiReaderMutableCollection? @Override @Test public void RichIterable_iterator_iterationOrder() { MutableCollection<Integer> iterationOrder = this.newMutableForFilter(); MultiReaderUnifiedSet<Integer> instanceUnderTest = this.newWith(4, 3, 2, 1); instanceUnderTest.withReadLockAndDelegate( delegate -> { Iterator<Integer> iterator = delegate.iterator(); while (iterator.hasNext()) { iterationOrder.add(iterator.next()); } }); assertEquals(this.expectedIterationOrder(), iterationOrder); }
private static void assertUnifiedSetReplace(int shift) { MultiReaderUnifiedSet<CollidingInt> set = MultiReaderUnifiedSet.newSet(); int size = 100000; for (int i = 0; i < size; i++) { set.add(new CollidingInt(i, shift)); } for (int i = 0; i < size; i++) { set.add(new CollidingInt(i, shift)); } Verify.assertSize(size, set); for (int i = 0; i < size; i++) { Verify.assertContains(new CollidingInt(i, shift), set); } }
@SafeVarargs @Override public final <T> MultiReaderUnifiedSet<T> newWith(T... elements) { MultiReaderUnifiedSet<T> result = MultiReaderUnifiedSet.newSet(); IterableTestCase.addAllTo(elements, result); return result; }
@Test public void MultiReaderUnifiedSet_next_throws_at_end() { MultiReaderUnifiedSet<Integer> iterable = this.newWith(3, 2, 1); iterable.withReadLockAndDelegate( delegate -> { Iterator<Integer> iterator = delegate.iterator(); assertTrue(iterator.hasNext()); iterator.next(); assertTrue(iterator.hasNext()); iterator.next(); assertTrue(iterator.hasNext()); iterator.next(); assertFalse(iterator.hasNext()); assertThrows(NoSuchElementException.class, (Runnable) iterator::next); }); }
private static void assertUnifiedSetForEach(int shift) { MultiReaderUnifiedSet<CollidingInt> set = MultiReaderUnifiedSet.newSet(); int size = 100000; for (int i = 0; i < size; i++) { Assert.assertTrue(set.add(new CollidingInt(i, shift))); } MutableList<CollidingInt> keys = FastList.newList(size); set.forEach(Procedures.cast(keys::add)); Verify.assertSize(size, keys); Collections.sort(keys); for (int i = 0; i < size; i++) { Verify.assertItemAtIndex(new CollidingInt(i, shift), i, keys); } }
private static void runUnifiedSetSerialize(int shift) { MultiReaderUnifiedSet<CollidingInt> set = MultiReaderUnifiedSet.newSet(); int size = 100000; for (int i = 0; i < size; i++) { set.add(new CollidingInt(i, shift)); } set.add(null); set = SerializeTestHelper.serializeDeserialize(set); Verify.assertSize(size + 1, set); for (int i = 0; i < size; i++) { Verify.assertContains(new CollidingInt(i, shift), set); } Verify.assertContains(null, set); }
private static void runUnifiedSetToArray(int shift) { MultiReaderUnifiedSet<CollidingInt> set = MultiReaderUnifiedSet.newSet(); int size = 100000; for (int i = 0; i < size; i++) { set.add(new CollidingInt(i, shift)); } Verify.assertSize(size, set); Object[] keys = set.toArray(); Assert.assertEquals(size, keys.length); Arrays.sort(keys); for (int i = 0; i < size; i++) { Verify.assertItemAtIndex(new CollidingInt(i, shift), i, keys); } }
private static void runUnifiedSetRetainAllFromSet(int shift) { MultiReaderUnifiedSet<CollidingInt> set = MultiReaderUnifiedSet.newSet(); Set<CollidingInt> toRetain = new HashSet<CollidingInt>(); int size = 100000; for (int i = 0; i < size; i++) { set.add(new CollidingInt(i, shift)); if (i % 2 == 0) { toRetain.add(new CollidingInt(i, shift)); } } Verify.assertSize(size, set); Assert.assertTrue(set.containsAll(toRetain)); Assert.assertTrue(set.retainAll(toRetain)); Assert.assertTrue(set.containsAll(toRetain)); Assert.assertFalse(set.retainAll(toRetain)); // a second call should not modify the set Verify.assertSize(size / 2, set); for (int i = 0; i < size; i += 2) { Verify.assertContains(new CollidingInt(i, shift), set); } }
@Test public void MultiReaderUnifiedSet_next() { MultiReaderUnifiedSet<Integer> iterable = this.newWith(3, 2, 1); MutableCollection<Integer> mutableCollection = this.newMutableForFilter(); iterable.withReadLockAndDelegate( delegate -> { Iterator<Integer> iterator = delegate.iterator(); while (iterator.hasNext()) { Integer integer = iterator.next(); mutableCollection.add(integer); } assertEquals(this.getExpectedFiltered(3, 2, 1), mutableCollection); assertFalse(iterator.hasNext()); }); }
@Test public void testUnifiedSetKeySetToArrayDest() { MutableSet<Integer> set = MultiReaderUnifiedSet.newSetWith(1, 2, 3, 4); // deliberately to small to force the method to allocate one of the correct size Integer[] dest = new Integer[2]; Integer[] result = set.toArray(dest); Verify.assertSize(4, result); Arrays.sort(result); Assert.assertArrayEquals(new Integer[] {1, 2, 3, 4}, result); }
@Test public void testUnifiedSet() { MultiReaderUnifiedSet<Integer> set = MultiReaderUnifiedSet.newSet(); int size = 100000; for (int i = 0; i < size; i++) { Assert.assertTrue(set.add(i)); } Verify.assertSize(size, set); for (int i = 0; i < size; i++) { Verify.assertContains(i, set); } for (int i = 0; i < size; i += 2) { Assert.assertTrue(set.remove(i)); } Verify.assertSize(size / 2, set); for (int i = 1; i < size; i += 2) { Verify.assertContains(i, set); } }
private static void assertUnifiedSetForEachWith(int shift) { MultiReaderUnifiedSet<CollidingInt> set = MultiReaderUnifiedSet.newSet(); int size = 100000; for (int i = 0; i < size; i++) { Assert.assertTrue(set.add(new CollidingInt(i, shift))); } MutableList<CollidingInt> keys = FastList.newList(size); set.forEachWith( (key, s) -> { Assert.assertEquals("foo", s); keys.add(key); }, "foo"); Verify.assertSize(size, keys); Collections.sort(keys); for (int i = 0; i < size; i++) { Verify.assertItemAtIndex(new CollidingInt(i, shift), i, keys); } }
private static void assertUnifiedSetEqualsAndHashCode(int shift) { MutableSet<CollidingInt> set1 = MultiReaderUnifiedSet.newSet(); Set<CollidingInt> set2 = new HashSet<CollidingInt>(); MutableSet<CollidingInt> set3 = MultiReaderUnifiedSet.newSet(); MutableSet<CollidingInt> set4 = MultiReaderUnifiedSet.newSet(); int size = 100000; for (int i = 0; i < size; i++) { set1.add(new CollidingInt(i, shift)); set2.add(new CollidingInt(i, shift)); set3.add(new CollidingInt(i, shift)); set4.add(new CollidingInt(size - i - 1, shift)); } Assert.assertEquals(set1, set2); Assert.assertEquals(set1.hashCode(), set2.hashCode()); Verify.assertSetsEqual(set1, set3); Verify.assertEqualsAndHashCode(set1, set3); Verify.assertSetsEqual(set2, set4); Assert.assertEquals(set4, set2); Assert.assertEquals(set2.hashCode(), set4.hashCode()); }
private void assertUnifiedSetPutDoesNotReplace(int shift) { MultiReaderUnifiedSet<CollidingIntWithFlag> set = MultiReaderUnifiedSet.newSet(); for (int i = 0; i < 1000; i++) { Assert.assertTrue(set.add(new CollidingIntWithFlag(i, shift, false))); } Assert.assertEquals(1000, set.size()); for (int i = 0; i < 1000; i++) { Assert.assertFalse(set.add(new CollidingIntWithFlag(i, shift, true))); } Assert.assertEquals(1000, set.size()); set.withReadLockAndDelegate( delegate -> { for (CollidingIntWithFlag ciwf : delegate) { Assert.assertFalse(ciwf.isFlag()); } }); }
private static void assertUnifiedSetAddAllWithHashSet(int shift) { Set<CollidingInt> set = new HashSet<CollidingInt>(); int size = 100000; for (int i = 0; i < size; i++) { set.add(new CollidingInt(i, shift)); } MultiReaderUnifiedSet<CollidingInt> newSet = MultiReaderUnifiedSet.newSet(size); newSet.addAll(set); Verify.assertSize(size, newSet); for (int i = 0; i < size; i++) { Verify.assertContains(new CollidingInt(i, shift), newSet); } MultiReaderUnifiedSet<CollidingInt> newSet2 = MultiReaderUnifiedSet.newSet(); newSet2.addAll(set); Verify.assertSize(size, newSet2); for (int i = 0; i < size; i++) { Verify.assertContains(new CollidingInt(i, shift), newSet2); } }
public class ParallelIterateAcceptanceTest { private static final Procedure<Integer> EXCEPTION_PROCEDURE = value -> { throw new RuntimeException("Thread death on its way!"); }; private static final ObjectIntProcedure<Integer> EXCEPTION_OBJECT_INT_PROCEDURE = (object, index) -> { throw new RuntimeException("Thread death on its way!"); }; private static final Function<Integer, Collection<String>> INT_TO_TWO_STRINGS = integer -> Lists.fixedSize.of(integer.toString(), integer.toString()); private static final Function0<AtomicInteger> ATOMIC_INTEGER_NEW = AtomicInteger::new; private static final Function<Integer, String> EVEN_OR_ODD = value -> value % 2 == 0 ? "Even" : "Odd"; private int count; private final MutableSet<String> threadNames = MultiReaderUnifiedSet.newSet(); private ImmutableList<RichIterable<Integer>> iterables; private final ExecutorService executor = Executors.newFixedThreadPool(2); @Before public void setUp() { Interval interval = Interval.oneTo(20000); this.iterables = Lists.immutable.of( interval.toList(), interval.toList().asUnmodifiable(), interval.toList().asSynchronized(), interval.toList().toImmutable(), interval.toSet(), interval.toSet().asUnmodifiable(), interval.toSet().asSynchronized(), interval.toSet().toImmutable(), interval.toBag(), interval.toBag().asUnmodifiable(), interval.toBag().asSynchronized(), interval.toBag().toImmutable(), interval.toSortedSet(), interval.toSortedSet().asUnmodifiable(), interval.toSortedSet().asSynchronized(), interval.toSortedSet().toImmutable(), interval.toMap(Functions.<Integer>getPassThru(), Functions.<Integer>getPassThru()), interval .toMap(Functions.<Integer>getPassThru(), Functions.<Integer>getPassThru()) .asUnmodifiable(), interval .toMap(Functions.<Integer>getPassThru(), Functions.<Integer>getPassThru()) .asSynchronized(), interval .toMap(Functions.<Integer>getPassThru(), Functions.<Integer>getPassThru()) .toImmutable(), ArrayListAdapter.<Integer>newList().withAll(interval), ArrayListAdapter.<Integer>newList().withAll(interval).asUnmodifiable(), ArrayListAdapter.<Integer>newList().withAll(interval).asSynchronized(), new CompositeFastList<Integer>().withAll(interval.toList()), new CompositeFastList<Integer>().withAll(interval.toList()).asUnmodifiable(), new CompositeFastList<Integer>().withAll(interval.toList()).asSynchronized(), new CompositeFastList<Integer>().withAll(interval.toList()).toImmutable(), ListAdapter.adapt(new LinkedList<Integer>()).withAll(interval), ListAdapter.adapt(new LinkedList<Integer>()).withAll(interval).asUnmodifiable(), ListAdapter.adapt(new LinkedList<Integer>()).withAll(interval).asSynchronized(), UnifiedSetWithHashingStrategy.<Integer>newSet(HashingStrategies.defaultStrategy()) .withAll(interval), UnifiedSetWithHashingStrategy.<Integer>newSet(HashingStrategies.defaultStrategy()) .withAll(interval) .asUnmodifiable(), UnifiedSetWithHashingStrategy.<Integer>newSet(HashingStrategies.defaultStrategy()) .withAll(interval) .asSynchronized(), UnifiedSetWithHashingStrategy.<Integer>newSet(HashingStrategies.defaultStrategy()) .withAll(interval) .toImmutable()); } @After public void tearDown() { this.executor.shutdown(); } @Test public void testOneLevelCall() { new RecursiveProcedure().value(1); synchronized (this) { Assert.assertEquals("all iterations completed", 20000, this.count); } } @Test public void testNestedCall() { new RecursiveProcedure().value(2); synchronized (this) { Assert.assertEquals("all iterations completed", 419980, this.count); } Assert.assertTrue("uses multiple threads", this.threadNames.size() > 1); } @Test public void testForEachUsingSet() { // Tests the default batch size calculations IntegerSum sum = new IntegerSum(0); MutableSet<Integer> set = Interval.toSet(1, 10000); ParallelIterate.forEach(set, new SumProcedure(sum), new SumCombiner(sum)); Assert.assertEquals(50005000, sum.getSum()); // Testing batch size 1 IntegerSum sum2 = new IntegerSum(0); UnifiedSet<Integer> set2 = UnifiedSet.newSet(Interval.oneTo(100)); ParallelIterate.forEach( set2, new SumProcedure(sum2), new SumCombiner(sum2), 1, set2.getBatchCount(set2.size())); Assert.assertEquals(5050, sum2.getSum()); // Testing an uneven batch size IntegerSum sum3 = new IntegerSum(0); UnifiedSet<Integer> set3 = UnifiedSet.newSet(Interval.oneTo(100)); ParallelIterate.forEach( set3, new SumProcedure(sum3), new SumCombiner(sum3), 1, set3.getBatchCount(13)); Assert.assertEquals(5050, sum3.getSum()); // Testing divideByZero exception by passing 1 as batchSize IntegerSum sum4 = new IntegerSum(0); UnifiedSet<Integer> set4 = UnifiedSet.newSet(Interval.oneTo(100)); ParallelIterate.forEach(set4, new SumProcedure(sum4), new SumCombiner(sum4), 1); Assert.assertEquals(5050, sum4.getSum()); } @Test public void testForEachUsingMap() { // Test the default batch size calculations IntegerSum sum1 = new IntegerSum(0); MutableMap<String, Integer> map1 = Interval.fromTo(1, 10000).toMap(String::valueOf, Functions.getIntegerPassThru()); ParallelIterate.forEach(map1, new SumProcedure(sum1), new SumCombiner(sum1)); Assert.assertEquals(50005000, sum1.getSum()); // Testing batch size 1 IntegerSum sum2 = new IntegerSum(0); UnifiedMap<String, Integer> map2 = (UnifiedMap<String, Integer>) Interval.fromTo(1, 100).toMap(String::valueOf, Functions.getIntegerPassThru()); ParallelIterate.forEach( map2, new SumProcedure(sum2), new SumCombiner(sum2), 1, map2.getBatchCount(map2.size())); Assert.assertEquals(5050, sum2.getSum()); // Testing an uneven batch size IntegerSum sum3 = new IntegerSum(0); UnifiedMap<String, Integer> set3 = (UnifiedMap<String, Integer>) Interval.fromTo(1, 100).toMap(String::valueOf, Functions.getIntegerPassThru()); ParallelIterate.forEach( set3, new SumProcedure(sum3), new SumCombiner(sum3), 1, set3.getBatchCount(13)); Assert.assertEquals(5050, sum3.getSum()); } @Test public void testForEach() { IntegerSum sum1 = new IntegerSum(0); List<Integer> list1 = ParallelIterateAcceptanceTest.createIntegerList(16); ParallelIterate.forEach( list1, new SumProcedure(sum1), new SumCombiner(sum1), 1, list1.size() / 2); Assert.assertEquals(16, sum1.getSum()); IntegerSum sum2 = new IntegerSum(0); List<Integer> list2 = ParallelIterateAcceptanceTest.createIntegerList(7); ParallelIterate.forEach(list2, new SumProcedure(sum2), new SumCombiner(sum2)); Assert.assertEquals(7, sum2.getSum()); IntegerSum sum3 = new IntegerSum(0); List<Integer> list3 = ParallelIterateAcceptanceTest.createIntegerList(15); ParallelIterate.forEach( list3, new SumProcedure(sum3), new SumCombiner(sum3), 1, list3.size() / 2); Assert.assertEquals(15, sum3.getSum()); IntegerSum sum4 = new IntegerSum(0); List<Integer> list4 = ParallelIterateAcceptanceTest.createIntegerList(35); ParallelIterate.forEach(list4, new SumProcedure(sum4), new SumCombiner(sum4)); Assert.assertEquals(35, sum4.getSum()); IntegerSum sum5 = new IntegerSum(0); MutableList<Integer> list5 = FastList.newList(list4); ParallelIterate.forEach(list5, new SumProcedure(sum5), new SumCombiner(sum5)); Assert.assertEquals(35, sum5.getSum()); IntegerSum sum6 = new IntegerSum(0); List<Integer> list6 = ParallelIterateAcceptanceTest.createIntegerList(40); ParallelIterate.forEach( list6, new SumProcedure(sum6), new SumCombiner(sum6), 1, list6.size() / 2); Assert.assertEquals(40, sum6.getSum()); IntegerSum sum7 = new IntegerSum(0); MutableList<Integer> list7 = FastList.newList(list6); ParallelIterate.forEach( list7, new SumProcedure(sum7), new SumCombiner(sum7), 1, list6.size() / 2); Assert.assertEquals(40, sum7.getSum()); } @Test public void testForEachImmutableList() { IntegerSum sum1 = new IntegerSum(0); ImmutableList<Integer> list1 = Lists.immutable.ofAll(ParallelIterateAcceptanceTest.createIntegerList(16)); ParallelIterate.forEach( list1, new SumProcedure(sum1), new SumCombiner(sum1), 1, list1.size() / 2); Assert.assertEquals(16, sum1.getSum()); IntegerSum sum2 = new IntegerSum(0); ImmutableList<Integer> list2 = Lists.immutable.ofAll(ParallelIterateAcceptanceTest.createIntegerList(7)); ParallelIterate.forEach(list2, new SumProcedure(sum2), new SumCombiner(sum2)); Assert.assertEquals(7, sum2.getSum()); IntegerSum sum3 = new IntegerSum(0); ImmutableList<Integer> list3 = Lists.immutable.ofAll(ParallelIterateAcceptanceTest.createIntegerList(15)); ParallelIterate.forEach( list3, new SumProcedure(sum3), new SumCombiner(sum3), 1, list3.size() / 2); Assert.assertEquals(15, sum3.getSum()); IntegerSum sum4 = new IntegerSum(0); ImmutableList<Integer> list4 = Lists.immutable.ofAll(ParallelIterateAcceptanceTest.createIntegerList(35)); ParallelIterate.forEach(list4, new SumProcedure(sum4), new SumCombiner(sum4)); Assert.assertEquals(35, sum4.getSum()); IntegerSum sum5 = new IntegerSum(0); ImmutableList<Integer> list5 = FastList.newList(list4).toImmutable(); ParallelIterate.forEach(list5, new SumProcedure(sum5), new SumCombiner(sum5)); Assert.assertEquals(35, sum5.getSum()); IntegerSum sum6 = new IntegerSum(0); ImmutableList<Integer> list6 = Lists.immutable.ofAll(ParallelIterateAcceptanceTest.createIntegerList(40)); ParallelIterate.forEach( list6, new SumProcedure(sum6), new SumCombiner(sum6), 1, list6.size() / 2); Assert.assertEquals(40, sum6.getSum()); IntegerSum sum7 = new IntegerSum(0); ImmutableList<Integer> list7 = FastList.newList(list6).toImmutable(); ParallelIterate.forEach( list7, new SumProcedure(sum7), new SumCombiner(sum7), 1, list6.size() / 2); Assert.assertEquals(40, sum7.getSum()); } @Test public void testForEachWithException() { Verify.assertThrows( RuntimeException.class, () -> ParallelIterate.forEach( ParallelIterateAcceptanceTest.createIntegerList(5), new PassThruProcedureFactory<>(EXCEPTION_PROCEDURE), new PassThruCombiner<>(), 1, 5)); } @Test public void testForEachWithIndexToArrayUsingFastListSerialPath() { Integer[] array = new Integer[200]; FastList<Integer> list = (FastList<Integer>) Interval.oneTo(200).toList(); Assert.assertTrue(ArrayIterate.allSatisfy(array, Predicates.isNull())); ParallelIterate.forEachWithIndex(list, (each, index) -> array[index] = each); Assert.assertArrayEquals(array, list.toArray(new Integer[] {})); } @Test public void testForEachWithIndexToArrayUsingFastList() { Integer[] array = new Integer[200]; FastList<Integer> list = (FastList<Integer>) Interval.oneTo(200).toList(); Assert.assertTrue(ArrayIterate.allSatisfy(array, Predicates.isNull())); ParallelIterate.forEachWithIndex(list, (each, index) -> array[index] = each, 10, 10); Assert.assertArrayEquals(array, list.toArray(new Integer[] {})); } @Test public void testForEachWithIndexToArrayUsingImmutableList() { Integer[] array = new Integer[200]; ImmutableList<Integer> list = Interval.oneTo(200).toList().toImmutable(); Assert.assertTrue(ArrayIterate.allSatisfy(array, Predicates.isNull())); ParallelIterate.forEachWithIndex(list, (each, index) -> array[index] = each, 10, 10); Assert.assertArrayEquals(array, list.toArray(new Integer[] {})); } @Test public void testForEachWithIndexToArrayUsingArrayList() { Integer[] array = new Integer[200]; List<Integer> list = new ArrayList<>(Interval.oneTo(200)); Assert.assertTrue(ArrayIterate.allSatisfy(array, Predicates.isNull())); ParallelIterate.forEachWithIndex(list, (each, index) -> array[index] = each, 10, 10); Assert.assertArrayEquals(array, list.toArray(new Integer[] {})); } @Test public void testForEachWithIndexToArrayUsingFixedArrayList() { Integer[] array = new Integer[10]; List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); Assert.assertTrue(ArrayIterate.allSatisfy(array, Predicates.isNull())); ParallelIterate.forEachWithIndex(list, (each, index) -> array[index] = each, 1, 2); Assert.assertArrayEquals(array, list.toArray(new Integer[list.size()])); } @Test public void testForEachWithIndexException() { Verify.assertThrows( RuntimeException.class, () -> ParallelIterate.forEachWithIndex( ParallelIterateAcceptanceTest.createIntegerList(5), new PassThruObjectIntProcedureFactory<>(EXCEPTION_OBJECT_INT_PROCEDURE), new PassThruCombiner<>(), 1, 5)); } @Test public void select() { this.iterables.forEach(Procedures.cast(this::basicSelect)); } private void basicSelect(RichIterable<Integer> iterable) { Collection<Integer> actual1 = ParallelIterate.select(iterable, Predicates.greaterThan(10000)); Collection<Integer> actual2 = ParallelIterate.select( iterable, Predicates.greaterThan(10000), HashBag.<Integer>newBag(), 3, this.executor, true); Collection<Integer> actual3 = ParallelIterate.select(iterable, Predicates.greaterThan(10000), true); RichIterable<Integer> expected = iterable.select(Predicates.greaterThan(10000)); Assert.assertEquals( expected.getClass().getSimpleName() + '/' + actual1.getClass().getSimpleName(), expected, actual1); Assert.assertEquals( expected.getClass().getSimpleName() + '/' + actual2.getClass().getSimpleName(), expected.toBag(), actual2); Assert.assertEquals( expected.getClass().getSimpleName() + '/' + actual3.getClass().getSimpleName(), expected.toBag(), HashBag.newBag(actual3)); } @Test public void selectSortedSet() { RichIterable<Integer> iterable = Interval.oneTo(20000).toSortedSet(); Collection<Integer> actual1 = ParallelIterate.select(iterable, Predicates.greaterThan(10000)); Collection<Integer> actual2 = ParallelIterate.select(iterable, Predicates.greaterThan(10000), true); RichIterable<Integer> expected = iterable.select(Predicates.greaterThan(10000)); Assert.assertSame(expected.getClass(), actual1.getClass()); Assert.assertSame(expected.getClass(), actual2.getClass()); Assert.assertEquals( expected.getClass().getSimpleName() + '/' + actual1.getClass().getSimpleName(), expected, actual1); Assert.assertEquals( expected.getClass().getSimpleName() + '/' + actual2.getClass().getSimpleName(), expected, actual2); } @Test public void count() { this.iterables.forEach(Procedures.cast(this::basicCount)); } private void basicCount(RichIterable<Integer> listIterable) { int actual1 = ParallelIterate.count(listIterable, Predicates.greaterThan(10000)); int actual2 = ParallelIterate.count(listIterable, Predicates.greaterThan(10000), 11, this.executor); Assert.assertEquals(10000, actual1); Assert.assertEquals(10000, actual2); } @Test public void reject() { this.iterables.forEach(Procedures.cast(this::basicReject)); } private void basicReject(RichIterable<Integer> iterable) { Collection<Integer> actual1 = ParallelIterate.reject(iterable, Predicates.greaterThan(10000)); Collection<Integer> actual2 = ParallelIterate.reject( iterable, Predicates.greaterThan(10000), HashBag.<Integer>newBag(), 3, this.executor, true); Collection<Integer> actual3 = ParallelIterate.reject(iterable, Predicates.greaterThan(10000), true); RichIterable<Integer> expected = iterable.reject(Predicates.greaterThan(10000)); Assert.assertEquals( expected.getClass().getSimpleName() + '/' + actual1.getClass().getSimpleName(), expected, actual1); Assert.assertEquals( expected.getClass().getSimpleName() + '/' + actual2.getClass().getSimpleName(), expected.toBag(), actual2); Assert.assertEquals( expected.getClass().getSimpleName() + '/' + actual3.getClass().getSimpleName(), expected.toBag(), HashBag.newBag(actual3)); } @Test public void collect() { this.iterables.forEach(Procedures.cast(this::basicCollect)); } private void basicCollect(RichIterable<Integer> iterable) { Collection<String> actual1 = ParallelIterate.collect(iterable, String::valueOf); Collection<String> actual2 = ParallelIterate.collect( iterable, String::valueOf, HashBag.<String>newBag(), 3, this.executor, false); Collection<String> actual3 = ParallelIterate.collect(iterable, String::valueOf, true); RichIterable<String> expected = iterable.collect(String::valueOf); Verify.assertSize(20000, actual1); Verify.assertContains(String.valueOf(20000), actual1); Assert.assertEquals( expected.getClass().getSimpleName() + '/' + actual1.getClass().getSimpleName(), expected, actual1); Assert.assertEquals( expected.getClass().getSimpleName() + '/' + actual2.getClass().getSimpleName(), expected.toBag(), actual2); Assert.assertEquals( expected.getClass().getSimpleName() + '/' + actual3.getClass().getSimpleName(), expected.toBag(), HashBag.newBag(actual3)); } @Test public void collectIf() { this.iterables.forEach(Procedures.cast(this::basicCollectIf)); } private void basicCollectIf(RichIterable<Integer> collection) { Predicate<Integer> greaterThan = Predicates.greaterThan(10000); Collection<String> actual1 = ParallelIterate.collectIf(collection, greaterThan, String::valueOf); Collection<String> actual2 = ParallelIterate.collectIf( collection, greaterThan, String::valueOf, HashBag.<String>newBag(), 3, this.executor, true); Collection<String> actual3 = ParallelIterate.collectIf( collection, greaterThan, String::valueOf, HashBag.<String>newBag(), 3, this.executor, true); Bag<String> expected = collection.collectIf(greaterThan, String::valueOf).toBag(); Verify.assertSize(10000, actual1); Verify.assertNotContains(String.valueOf(9000), actual1); Verify.assertNotContains(String.valueOf(21000), actual1); Verify.assertContains(String.valueOf(15976), actual1); Assert.assertEquals( expected.getClass().getSimpleName() + '/' + actual1.getClass().getSimpleName(), expected, HashBag.newBag(actual1)); Assert.assertEquals( expected.getClass().getSimpleName() + '/' + actual2.getClass().getSimpleName(), expected, actual2); Assert.assertEquals( expected.getClass().getSimpleName() + '/' + actual3.getClass().getSimpleName(), expected, actual3); } @Test public void flatCollect() { this.iterables.forEach(Procedures.cast(this::basicFlatCollect)); } private void basicFlatCollect(RichIterable<Integer> iterable) { Collection<String> actual1 = ParallelIterate.flatCollect(iterable, INT_TO_TWO_STRINGS); Collection<String> actual2 = ParallelIterate.flatCollect( iterable, INT_TO_TWO_STRINGS, HashBag.<String>newBag(), 3, this.executor, false); Collection<String> actual3 = ParallelIterate.flatCollect(iterable, INT_TO_TWO_STRINGS, true); RichIterable<String> expected1 = iterable.flatCollect(INT_TO_TWO_STRINGS); RichIterable<String> expected2 = iterable.flatCollect(INT_TO_TWO_STRINGS, HashBag.<String>newBag()); Verify.assertContains(String.valueOf(20000), actual1); Assert.assertEquals( expected1.getClass().getSimpleName() + '/' + actual1.getClass().getSimpleName(), expected1, actual1); Assert.assertEquals( expected2.getClass().getSimpleName() + '/' + actual2.getClass().getSimpleName(), expected2, actual2); Assert.assertEquals( expected1.getClass().getSimpleName() + '/' + actual3.getClass().getSimpleName(), expected1.toBag(), HashBag.newBag(actual3)); } @Test public void groupBy() { FastList<Integer> iterable = FastList.newWithNValues( 10000000, new Function0<Integer>() { private int current; public Integer value() { if (this.current < 4) { return Integer.valueOf(this.current++); } this.current = 0; return Integer.valueOf(4); } }); iterable.shuffleThis(); Multimap<String, Integer> expected = iterable.toBag().groupBy(String::valueOf); Multimap<String, Integer> expectedAsSet = iterable.toSet().groupBy(String::valueOf); Multimap<String, Integer> result1 = ParallelIterate.groupBy(iterable.toList(), String::valueOf, 100); Assert.assertEquals(expected, HashBagMultimap.newMultimap(result1)); Multimap<String, Integer> result2 = ParallelIterate.groupBy(iterable.toList(), String::valueOf); Assert.assertEquals(expected, HashBagMultimap.newMultimap(result2)); Multimap<String, Integer> result3 = ParallelIterate.groupBy( iterable.toSet(), String::valueOf, SynchronizedPutUnifiedSetMultimap.<String, Integer>newMultimap(), 100); Assert.assertEquals(expectedAsSet, result3); Multimap<String, Integer> result4 = ParallelIterate.groupBy( iterable.toSet(), String::valueOf, SynchronizedPutUnifiedSetMultimap.<String, Integer>newMultimap()); Assert.assertEquals(expectedAsSet, result4); Multimap<String, Integer> result5 = ParallelIterate.groupBy( iterable.toSortedSet(), String::valueOf, SynchronizedPutUnifiedSetMultimap.<String, Integer>newMultimap(), 100); Assert.assertEquals(expectedAsSet, result5); Multimap<String, Integer> result6 = ParallelIterate.groupBy( iterable.toSortedSet(), String::valueOf, SynchronizedPutUnifiedSetMultimap.<String, Integer>newMultimap()); Assert.assertEquals(expectedAsSet, result6); Multimap<String, Integer> result7 = ParallelIterate.groupBy( iterable.toBag(), String::valueOf, SynchronizedPutHashBagMultimap.<String, Integer>newMultimap(), 100); Assert.assertEquals(expected, result7); Multimap<String, Integer> result8 = ParallelIterate.groupBy( iterable.toBag(), String::valueOf, SynchronizedPutHashBagMultimap.<String, Integer>newMultimap()); Assert.assertEquals(expected, result8); Multimap<String, Integer> result9 = ParallelIterate.groupBy(iterable.toList().toImmutable(), String::valueOf); Assert.assertEquals(expected, HashBagMultimap.newMultimap(result9)); Multimap<String, Integer> result10 = ParallelIterate.groupBy(iterable.toSortedList(), String::valueOf, 100); Assert.assertEquals(expected, HashBagMultimap.newMultimap(result10)); Multimap<String, Integer> result11 = ParallelIterate.groupBy(iterable.toSortedList(), String::valueOf); Assert.assertEquals(expected, HashBagMultimap.newMultimap(result11)); Multimap<String, Integer> result12 = ParallelIterate.groupBy( iterable, String::valueOf, MultiReaderFastListMultimap.<String, Integer>newMultimap(), 100); Assert.assertEquals(expected, HashBagMultimap.newMultimap(result12)); Multimap<String, Integer> result13 = ParallelIterate.groupBy( iterable, String::valueOf, MultiReaderFastListMultimap.<String, Integer>newMultimap()); Assert.assertEquals(expected, HashBagMultimap.newMultimap(result13)); Multimap<String, Integer> result14 = ParallelIterate.groupBy( iterable, String::valueOf, MultiReaderHashBagMultimap.<String, Integer>newMultimap(), 100); Assert.assertEquals(expected, result14); Multimap<String, Integer> result15 = ParallelIterate.groupBy( iterable, String::valueOf, MultiReaderHashBagMultimap.<String, Integer>newMultimap()); Assert.assertEquals(expected, result15); Multimap<String, Integer> result16 = ParallelIterate.groupBy( iterable, String::valueOf, MultiReaderUnifiedSetMultimap.<String, Integer>newMultimap(), 100); Assert.assertEquals(expectedAsSet, result16); Multimap<String, Integer> result17 = ParallelIterate.groupBy( iterable, String::valueOf, MultiReaderUnifiedSetMultimap.<String, Integer>newMultimap()); Assert.assertEquals(expectedAsSet, result17); } @Test public void aggregateInPlaceBy() { Procedure2<AtomicInteger, Integer> countAggregator = (aggregate, value) -> aggregate.incrementAndGet(); List<Integer> list = Interval.oneTo(20000); MutableMap<String, AtomicInteger> aggregation = ParallelIterate.aggregateInPlaceBy(list, EVEN_OR_ODD, ATOMIC_INTEGER_NEW, countAggregator); Assert.assertEquals(10000, aggregation.get("Even").intValue()); Assert.assertEquals(10000, aggregation.get("Odd").intValue()); ParallelIterate.aggregateInPlaceBy( list, EVEN_OR_ODD, ATOMIC_INTEGER_NEW, countAggregator, aggregation); Assert.assertEquals(20000, aggregation.get("Even").intValue()); Assert.assertEquals(20000, aggregation.get("Odd").intValue()); } @Test public void aggregateInPlaceByWithBatchSize() { MutableList<Integer> list = LazyIterate.adapt(Collections.nCopies(1000, 1)) .concatenate(Collections.nCopies(2000, 2)) .concatenate(Collections.nCopies(3000, 3)) .toList() .shuffleThis(); MapIterable<String, AtomicInteger> aggregation = ParallelIterate.aggregateInPlaceBy( list, String::valueOf, ATOMIC_INTEGER_NEW, AtomicInteger::addAndGet, 100); Assert.assertEquals(1000, aggregation.get("1").intValue()); Assert.assertEquals(4000, aggregation.get("2").intValue()); Assert.assertEquals(9000, aggregation.get("3").intValue()); } private static List<Integer> createIntegerList(int size) { return Collections.nCopies(size, Integer.valueOf(1)); } private class RecursiveProcedure implements Procedure<Integer> { private static final long serialVersionUID = 1L; private final ExecutorService executorService = ParallelIterate.newPooledExecutor("ParallelIterateTest", false); @Override public void value(Integer level) { if (level > 0) { ParallelIterateAcceptanceTest.this.threadNames.add(Thread.currentThread().getName()); this.executeParallelIterate(level - 1, this.executorService); } else { this.simulateWork(); } } private void simulateWork() { synchronized (ParallelIterateAcceptanceTest.this) { ParallelIterateAcceptanceTest.this.count++; } } private void executeParallelIterate(int level, ExecutorService executorService) { MutableList<Integer> items = Lists.mutable.of(); for (int i = 0; i < 20000; i++) { items.add(i % 1000 == 0 ? level : 0); } ParallelIterate.forEach(items, new RecursiveProcedure(), executorService); } } public static final class IntegerSum { private int sum; public IntegerSum(int newSum) { this.sum = newSum; } public IntegerSum add(int value) { this.sum += value; return this; } public int getSum() { return this.sum; } } public static final class SumProcedure implements Procedure<Integer>, Function2<IntegerSum, Integer, IntegerSum>, ProcedureFactory<SumProcedure> { private static final long serialVersionUID = 1L; private final IntegerSum sum; public SumProcedure(IntegerSum newSum) { this.sum = newSum; } @Override public SumProcedure create() { return new SumProcedure(new IntegerSum(0)); } @Override public IntegerSum value(IntegerSum s1, Integer s2) { return s1.add(s2); } @Override public void value(Integer object) { this.sum.add(object); } public int getSum() { return this.sum.getSum(); } } public static final class SumCombiner extends AbstractProcedureCombiner<SumProcedure> { private static final long serialVersionUID = 1L; private final IntegerSum sum; public SumCombiner(IntegerSum initialSum) { super(true); this.sum = initialSum; } @Override public void combineOne(SumProcedure sumProcedure) { this.sum.add(sumProcedure.getSum()); } } }