view test/java/util/stream/test/org/openjdk/tests/java/util/stream/DistinctOpTest.java @ 10544:18c111c17231

8027316: Distinct operation on an unordered stream should not be a barrier Reviewed-by: henryjen, mduigou, briangoetz
author psandoz
date Thu, 31 Oct 2013 11:59:04 +0100
parents be096613bfb5
children
line wrap: on
line source

/*
 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package org.openjdk.tests.java.util.stream;

import org.testng.annotations.Test;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.*;

import static java.util.stream.LambdaTestHelpers.*;

/**
 * DistinctOpTest
 */
@Test
public class DistinctOpTest extends OpTestCase {

    public void testUniqOp() {
        assertCountSum(repeat(0, 10).stream().distinct(), 1, 0);
        assertCountSum(repeat(1, 10).stream().distinct(), 1, 1);
        assertCountSum(countTo(0).stream().distinct(), 0, 0);
        assertCountSum(countTo(10).stream().distinct(), 10, 55);
        assertCountSum(countTo(10).stream().distinct(), 10, 55);
    }

    public void testWithUnorderedInfiniteStream() {
        // These tests should short-circuit, otherwise will fail with a time-out
        // or an OOME

        Integer one = Stream.iterate(1, i -> i + 1).unordered().parallel().distinct().findAny().get();
        assertEquals(one.intValue(), 1);

        Optional<Integer> oi = ThreadLocalRandom.current().ints().boxed().parallel().distinct().findAny();
        assertTrue(oi.isPresent());
    }

    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
    public void testOp(String name, TestData.OfRef<Integer> data) {
        Collection<Integer> result = exerciseOpsInt(data, Stream::distinct, IntStream::distinct, LongStream::distinct, DoubleStream::distinct);

        assertUnique(result);
        assertTrue((data.size() > 0) ? result.size() > 0 : result.size() == 0);
        assertTrue(result.size() <= data.size());
    }

    @Test(dataProvider = "withNull:StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
    public void testOpWithNull(String name, TestData.OfRef<Integer> data) {
        Collection<Integer> node = exerciseOps(data, Stream::distinct);
        assertUnique(node);

        node = withData(data).
                stream(s -> s.unordered().distinct()).
                exercise();
        assertUnique(node);

        node = exerciseOps(data, s -> s.distinct().distinct());
        assertUnique(node);
    }

    @Test(dataProvider = "withNull:StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
    public void testOpWithNullSorted(String name, TestData.OfRef<Integer> data) {
        List<Integer> l = new ArrayList<>();
        data.into(l).sort(cNullInteger);
        // Need to inject SORTED into the sorted list source since
        // sorted() with a comparator ironically clears SORTED
        Collection<Integer> node = exerciseOps(new SortedTestData<>(l), Stream::distinct);
        assertUnique(node);
        assertSorted(node, cNullInteger);
    }

    @SuppressWarnings("serial")
    static class SortedTestData<T> extends TestData.AbstractTestData.RefTestData<T, List<T>> {
        SortedTestData(List<T> coll) {
            super("SortedTestData", coll,
                  c -> StreamSupport.stream(Spliterators.spliterator(c.toArray(), Spliterator.ORDERED | Spliterator.SORTED), false),
                  c -> StreamSupport.stream(Spliterators.spliterator(c.toArray(), Spliterator.ORDERED | Spliterator.SORTED), true),
                  c -> Spliterators.spliterator(c.toArray(), Spliterator.ORDERED | Spliterator.SORTED),
                  List::size);
        }
    }

    public static final Comparator<Integer> cNullInteger = (a, b) -> {
        if (a == null && b == null) {
            return 0;
        }
        else if (a == null) {
            return -1;
        }
        else if (b == null) {
            return 1;
        }
        else {
            return Integer.compare(a, b);
        }
    };

    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
    public void testDistinctDistinct(String name, TestData.OfRef<Integer> data) {
        Collection<Integer> result = withData(data)
                .stream(s -> s.distinct().distinct(), new CollectorOps.TestParallelSizedOp<>())
                .exercise();
        assertUnique(result);
    }

    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
    public void testDistinctSorted(String name, TestData.OfRef<Integer> data) {
        Collection<Integer> result = withData(data)
                .stream(s -> s.distinct().sorted(),
                        new CollectorOps.TestParallelSizedOp<>())
                .exercise();
        assertUnique(result);
        assertSorted(result);
    }

    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
    public void testSortedDistinct(String name, TestData.OfRef<Integer> data) {
        Collection<Integer> result = withData(data)
                .stream(s -> s.sorted().distinct(),
                        new CollectorOps.TestParallelSizedOp<>())
                .exercise();
        assertUnique(result);
        assertSorted(result);
    }
}