Search in sources :

Example 1 with TailSpliterator

use of one.util.streamex.Internals.TailSpliterator in project streamex by amaembo.

the class TestHelpers method checkSpliterator.

/*
     * Tests whether spliterators produced by given supplier produce the
     * expected result under various splittings
     * 
     * This test is single-threaded. Its behavior is randomized, but random seed
     * will be printed in case of failure, so the results could be reproduced
     */
public static <T> void checkSpliterator(String msg, List<T> expected, Supplier<Spliterator<T>> supplier) {
    List<T> seq = new ArrayList<>();
    // Test characteristics
    Spliterator<T> forCharacteristics = supplier.get();
    if (forCharacteristics.hasCharacteristics(Spliterator.SORTED)) {
        // must not fail
        forCharacteristics.getComparator();
    }
    assertTrue(forCharacteristics.estimateSize() >= 0);
    // Test forEachRemaining
    Spliterator<T> sequential = supplier.get();
    sequential.forEachRemaining(seq::add);
    assertFalse(msg, sequential.tryAdvance(t -> fail(msg + ": Advance called with " + t)));
    sequential.forEachRemaining(t -> fail(msg + ": Advance called with " + t));
    assertEquals(msg, expected, seq);
    // Test tryAdvance
    seq.clear();
    sequential = supplier.get();
    while (true) {
        AtomicBoolean called = new AtomicBoolean();
        boolean res = sequential.tryAdvance(t -> {
            seq.add(t);
            called.set(true);
        });
        if (res != called.get()) {
            fail(msg + (res ? ": Consumer not called, but spliterator returned true" : ": Consumer called, but spliterator returned false"));
        }
        if (!res)
            break;
    }
    assertFalse(msg, sequential.tryAdvance(t -> fail(msg + ": Advance called with " + t)));
    assertEquals(msg, expected, seq);
    // Test TailSpliterator
    if (sequential instanceof TailSpliterator) {
        seq.clear();
        TailSpliterator.forEachWithTail(supplier.get(), seq::add);
        assertEquals(msg, expected, seq);
        seq.clear();
        sequential = supplier.get();
        while (sequential != null) {
            sequential = TailSpliterator.tryAdvanceWithTail(sequential, seq::add);
        }
    }
    assertEquals(msg, expected, seq);
    // Test advance+remaining
    for (int i = 1; i < Math.min(4, expected.size() - 1); i++) {
        seq.clear();
        sequential = supplier.get();
        for (int j = 0; j < i; j++) assertTrue(msg, sequential.tryAdvance(seq::add));
        sequential.forEachRemaining(seq::add);
        assertEquals(msg, expected, seq);
    }
    // Test trySplit
    withRandom(r -> {
        repeat(500, n -> {
            Spliterator<T> spliterator = supplier.get();
            List<Spliterator<T>> spliterators = new ArrayList<>();
            spliterators.add(spliterator);
            int p = r.nextInt(10) + 2;
            for (int i = 0; i < p; i++) {
                int idx = r.nextInt(spliterators.size());
                Spliterator<T> split = spliterators.get(idx).trySplit();
                if (split != null)
                    spliterators.add(idx, split);
            }
            List<Integer> order = IntStreamEx.ofIndices(spliterators).boxed().toMutableList();
            Collections.shuffle(order, r);
            List<T> list = StreamEx.of(order).mapToEntry(idx -> {
                Spliterator<T> s = spliterators.get(idx);
                Stream.Builder<T> builder = Stream.builder();
                s.forEachRemaining(builder);
                assertFalse(msg, s.tryAdvance(t -> fail(msg + ": Advance called with " + t)));
                s.forEachRemaining(t -> fail(msg + ": Advance called with " + t));
                return builder.build();
            }).sortedBy(Entry::getKey).values().flatMap(Function.identity()).toList();
            assertEquals(msg, expected, list);
        });
        repeat(500, n -> {
            Spliterator<T> spliterator = supplier.get();
            List<Spliterator<T>> spliterators = new ArrayList<>();
            spliterators.add(spliterator);
            int p = r.nextInt(30) + 2;
            for (int i = 0; i < p; i++) {
                int idx = r.nextInt(spliterators.size());
                Spliterator<T> split = spliterators.get(idx).trySplit();
                if (split != null)
                    spliterators.add(idx, split);
            }
            List<List<T>> results = StreamEx.<List<T>>generate(ArrayList::new).limit(spliterators.size()).toMutableList();
            int count = spliterators.size();
            while (count > 0) {
                int i;
                do {
                    i = r.nextInt(spliterators.size());
                    spliterator = spliterators.get(i);
                } while (spliterator == null);
                if (!spliterator.tryAdvance(results.get(i)::add)) {
                    spliterators.set(i, null);
                    count--;
                }
            }
            List<T> list = StreamEx.of(results).flatMap(List::stream).toList();
            assertEquals(msg, expected, list);
        });
    });
}
Also used : IntStream(java.util.stream.IntStream) Spliterators(java.util.Spliterators) IntConsumer(java.util.function.IntConsumer) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Random(java.util.Random) Function(java.util.function.Function) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) Assert.fail(org.junit.Assert.fail) Collector(java.util.stream.Collector) TailSpliterator(one.util.streamex.Internals.TailSpliterator) LongStream(java.util.stream.LongStream) Predicate(java.util.function.Predicate) Assert.assertNotNull(org.junit.Assert.assertNotNull) Internals.finished(one.util.streamex.Internals.finished) Set(java.util.Set) Assert.assertTrue(org.junit.Assert.assertTrue) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) Consumer(java.util.function.Consumer) List(java.util.List) Stream(java.util.stream.Stream) Assert.assertNull(org.junit.Assert.assertNull) Assert.assertFalse(org.junit.Assert.assertFalse) Entry(java.util.Map.Entry) Comparator(java.util.Comparator) Collections(java.util.Collections) Spliterator(java.util.Spliterator) Assert.assertEquals(org.junit.Assert.assertEquals) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) ComparisonFailure(org.junit.ComparisonFailure) ArrayList(java.util.ArrayList) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) TailSpliterator(one.util.streamex.Internals.TailSpliterator) IntStream(java.util.stream.IntStream) LongStream(java.util.stream.LongStream) Stream(java.util.stream.Stream) ArrayList(java.util.ArrayList) List(java.util.List) TailSpliterator(one.util.streamex.Internals.TailSpliterator) Spliterator(java.util.Spliterator)

Aggregations

ArrayList (java.util.ArrayList)1 Collections (java.util.Collections)1 Comparator (java.util.Comparator)1 List (java.util.List)1 Map (java.util.Map)1 Entry (java.util.Map.Entry)1 Objects (java.util.Objects)1 Random (java.util.Random)1 Set (java.util.Set)1 Spliterator (java.util.Spliterator)1 Spliterators (java.util.Spliterators)1 ConcurrentLinkedQueue (java.util.concurrent.ConcurrentLinkedQueue)1 ThreadLocalRandom (java.util.concurrent.ThreadLocalRandom)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 Consumer (java.util.function.Consumer)1 Function (java.util.function.Function)1 IntConsumer (java.util.function.IntConsumer)1 Predicate (java.util.function.Predicate)1 Supplier (java.util.function.Supplier)1