jdk/src/share/classes/java/util/stream/SliceOps.java
author henryjen
Mon, 08 Jul 2013 15:46:26 -0400
changeset 18825 06636235cd12
parent 18770 b71393f8e3e4
child 19218 8e7212b90b81
permissions -rw-r--r--
8020062: Nest StreamBuilder interfaces inside relevant Stream interfaces Reviewed-by: psandoz, mduigou Contributed-by: brian goetz <brian.goetz@oracle.com>
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
     1
/*
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
     2
 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
     4
 *
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    10
 *
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    15
 * accompanied this code).
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    16
 *
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    20
 *
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    23
 * questions.
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    24
 */
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    25
package java.util.stream;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    26
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    27
import java.util.Spliterator;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    28
import java.util.concurrent.CountedCompleter;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    29
import java.util.function.IntFunction;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    30
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    31
/**
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    32
 * Factory for instances of a short-circuiting stateful intermediate operations
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    33
 * that produce subsequences of their input stream.
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    34
 *
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    35
 * @since 1.8
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    36
 */
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    37
final class SliceOps {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    38
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    39
    // No instances
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    40
    private SliceOps() { }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    41
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
    42
    /**
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    43
     * Calculates the sliced size given the current size, number of elements
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    44
     * skip, and the number of elements to limit.
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    45
     *
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    46
     * @param size the current size
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    47
     * @param skip the number of elements to skip, assumed to be >= 0
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    48
     * @param limit the number of elements to limit, assumed to be >= 0, with
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    49
     *        a value of {@code Long.MAX_VALUE} if there is no limit
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    50
     * @return the sliced size
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    51
     */
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    52
    private static long calcSize(long size, long skip, long limit) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    53
        return size >= 0 ? Math.max(-1, Math.min(size - skip, limit)) : -1;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    54
    }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    55
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    56
    /**
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    57
     * Calculates the slice fence, which is one past the index of the slice
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    58
     * range
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    59
     * @param skip the number of elements to skip, assumed to be >= 0
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    60
     * @param limit the number of elements to limit, assumed to be >= 0, with
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    61
     *        a value of {@code Long.MAX_VALUE} if there is no limit
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    62
     * @return the slice fence.
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    63
     */
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    64
    private static long calcSliceFence(long skip, long limit) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    65
        long sliceFence = limit >= 0 ? skip + limit : Long.MAX_VALUE;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    66
        // Check for overflow
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    67
        return (sliceFence >= 0) ? sliceFence : Long.MAX_VALUE;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    68
    }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    69
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    70
    /**
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    71
     * Creates a slice spliterator given a stream shape governing the
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    72
     * spliterator type.  Requires that the underlying Spliterator
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    73
     * be SUBSIZED.
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    74
     */
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    75
    @SuppressWarnings("unchecked")
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    76
    private static <P_IN> Spliterator<P_IN> sliceSpliterator(StreamShape shape,
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    77
                                                             Spliterator<P_IN> s,
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    78
                                                             long skip, long limit) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    79
        assert s.hasCharacteristics(Spliterator.SUBSIZED);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    80
        long sliceFence = calcSliceFence(skip, limit);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    81
        switch (shape) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    82
            case REFERENCE:
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    83
                return new StreamSpliterators
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    84
                        .SliceSpliterator.OfRef<>(s, skip, sliceFence);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    85
            case INT_VALUE:
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    86
                return (Spliterator<P_IN>) new StreamSpliterators
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    87
                        .SliceSpliterator.OfInt((Spliterator.OfInt) s, skip, sliceFence);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    88
            case LONG_VALUE:
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    89
                return (Spliterator<P_IN>) new StreamSpliterators
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    90
                        .SliceSpliterator.OfLong((Spliterator.OfLong) s, skip, sliceFence);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    91
            case DOUBLE_VALUE:
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    92
                return (Spliterator<P_IN>) new StreamSpliterators
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    93
                        .SliceSpliterator.OfDouble((Spliterator.OfDouble) s, skip, sliceFence);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    94
            default:
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    95
                throw new IllegalStateException("Unknown shape " + shape);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    96
        }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    97
    }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    98
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
    99
    /**
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   100
     * Appends a "slice" operation to the provided stream.  The slice operation
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   101
     * may be may be skip-only, limit-only, or skip-and-limit.
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   102
     *
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   103
     * @param <T> the type of both input and output elements
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   104
     * @param upstream a reference stream with element type T
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   105
     * @param skip the number of elements to skip.  Must be >= 0.
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   106
     * @param limit the maximum size of the resulting stream, or -1 if no limit
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   107
     *        is to be imposed
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   108
     */
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   109
    public static <T> Stream<T> makeRef(AbstractPipeline<?, T, ?> upstream,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   110
                                       long skip, long limit) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   111
        if (skip < 0)
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   112
            throw new IllegalArgumentException("Skip must be non-negative: " + skip);
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   113
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   114
        return new ReferencePipeline.StatefulOp<T,T>(upstream, StreamShape.REFERENCE,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   115
                                                     flags(limit)) {
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   116
            Spliterator<T> unorderedSkipLimitSpliterator(Spliterator<T> s,
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   117
                                                         long skip, long limit, long sizeIfKnown) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   118
                if (skip <= sizeIfKnown) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   119
                    // Use just the limit if the number of elements
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   120
                    // to skip is <= the known pipeline size
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   121
                    limit = limit >= 0 ? Math.min(limit, sizeIfKnown - skip) : sizeIfKnown - skip;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   122
                    skip = 0;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   123
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   124
                return new StreamSpliterators.UnorderedSliceSpliterator.OfRef<>(s, skip, limit);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   125
            }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   126
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   127
            @Override
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   128
            <P_IN> Spliterator<T> opEvaluateParallelLazy(PipelineHelper<T> helper, Spliterator<P_IN> spliterator) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   129
                long size = helper.exactOutputSizeIfKnown(spliterator);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   130
                if (size > 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   131
                    return new StreamSpliterators.SliceSpliterator.OfRef<>(
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   132
                            helper.wrapSpliterator(spliterator),
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   133
                            skip,
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   134
                            calcSliceFence(skip, limit));
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   135
                } else if (!StreamOpFlag.ORDERED.isKnown(helper.getStreamAndOpFlags())) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   136
                    return unorderedSkipLimitSpliterator(
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   137
                            helper.wrapSpliterator(spliterator),
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   138
                            skip, limit, size);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   139
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   140
                else {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   141
                    // @@@ OOMEs will occur for LongStream.longs().filter(i -> true).limit(n)
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   142
                    //     regardless of the value of n
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   143
                    //     Need to adjust the target size of splitting for the
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   144
                    //     SliceTask from say (size / k) to say min(size / k, 1 << 14)
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   145
                    //     This will limit the size of the buffers created at the leaf nodes
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   146
                    //     cancellation will be more aggressive cancelling later tasks
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   147
                    //     if the target slice size has been reached from a given task,
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   148
                    //     cancellation should also clear local results if any
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   149
                    return new SliceTask<>(this, helper, spliterator, i -> (T[]) new Object[i], skip, limit).
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   150
                            invoke().spliterator();
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   151
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   152
            }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   153
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   154
            @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   155
            <P_IN> Node<T> opEvaluateParallel(PipelineHelper<T> helper,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   156
                                              Spliterator<P_IN> spliterator,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   157
                                              IntFunction<T[]> generator) {
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   158
                long size = helper.exactOutputSizeIfKnown(spliterator);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   159
                if (size > 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   160
                    // Because the pipeline is SIZED the slice spliterator
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   161
                    // can be created from the source, this requires matching
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   162
                    // to shape of the source, and is potentially more efficient
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   163
                    // than creating the slice spliterator from the pipeline
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   164
                    // wrapping spliterator
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   165
                    Spliterator<P_IN> s = sliceSpliterator(helper.getSourceShape(), spliterator, skip, limit);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   166
                    return Nodes.collect(helper, s, true, generator);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   167
                } else if (!StreamOpFlag.ORDERED.isKnown(helper.getStreamAndOpFlags())) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   168
                    Spliterator<T> s =  unorderedSkipLimitSpliterator(
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   169
                            helper.wrapSpliterator(spliterator),
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   170
                            skip, limit, size);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   171
                    // Collect using this pipeline, which is empty and therefore
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   172
                    // can be used with the pipeline wrapping spliterator
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   173
                    // Note that we cannot create a slice spliterator from
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   174
                    // the source spliterator if the pipeline is not SIZED
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   175
                    return Nodes.collect(this, s, true, generator);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   176
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   177
                else {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   178
                    return new SliceTask<>(this, helper, spliterator, generator, skip, limit).
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   179
                            invoke();
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   180
                }
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   181
            }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   183
            @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   184
            Sink<T> opWrapSink(int flags, Sink<T> sink) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   185
                return new Sink.ChainedReference<T>(sink) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   186
                    long n = skip;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   187
                    long m = limit >= 0 ? limit : Long.MAX_VALUE;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   188
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   189
                    @Override
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   190
                    public void begin(long size) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   191
                        downstream.begin(calcSize(size, skip, m));
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   192
                    }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   193
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   194
                    @Override
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   195
                    public void accept(T t) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   196
                        if (n == 0) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   197
                            if (m > 0) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   198
                                m--;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   199
                                downstream.accept(t);
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   200
                            }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   201
                        }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   202
                        else {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   203
                            n--;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   204
                        }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   205
                    }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   206
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   207
                    @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   208
                    public boolean cancellationRequested() {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   209
                        return m == 0 || downstream.cancellationRequested();
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   210
                    }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   211
                };
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   212
            }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   213
        };
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   214
    }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   215
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   216
    /**
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   217
     * Appends a "slice" operation to the provided IntStream.  The slice
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   218
     * operation may be may be skip-only, limit-only, or skip-and-limit.
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   219
     *
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   220
     * @param upstream An IntStream
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   221
     * @param skip The number of elements to skip.  Must be >= 0.
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   222
     * @param limit The maximum size of the resulting stream, or -1 if no limit
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   223
     *        is to be imposed
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   224
     */
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   225
    public static IntStream makeInt(AbstractPipeline<?, Integer, ?> upstream,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   226
                                    long skip, long limit) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   227
        if (skip < 0)
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   228
            throw new IllegalArgumentException("Skip must be non-negative: " + skip);
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   229
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   230
        return new IntPipeline.StatefulOp<Integer>(upstream, StreamShape.INT_VALUE,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   231
                                                   flags(limit)) {
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   232
            Spliterator.OfInt unorderedSkipLimitSpliterator(
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   233
                    Spliterator.OfInt s, long skip, long limit, long sizeIfKnown) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   234
                if (skip <= sizeIfKnown) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   235
                    // Use just the limit if the number of elements
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   236
                    // to skip is <= the known pipeline size
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   237
                    limit = limit >= 0 ? Math.min(limit, sizeIfKnown - skip) : sizeIfKnown - skip;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   238
                    skip = 0;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   239
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   240
                return new StreamSpliterators.UnorderedSliceSpliterator.OfInt(s, skip, limit);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   241
            }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   242
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   243
            @Override
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   244
            <P_IN> Spliterator<Integer> opEvaluateParallelLazy(PipelineHelper<Integer> helper,
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   245
                                                               Spliterator<P_IN> spliterator) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   246
                long size = helper.exactOutputSizeIfKnown(spliterator);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   247
                if (size > 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   248
                    return new StreamSpliterators.SliceSpliterator.OfInt(
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   249
                            (Spliterator.OfInt) helper.wrapSpliterator(spliterator),
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   250
                            skip,
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   251
                            calcSliceFence(skip, limit));
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   252
                } else if (!StreamOpFlag.ORDERED.isKnown(helper.getStreamAndOpFlags())) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   253
                    return unorderedSkipLimitSpliterator(
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   254
                            (Spliterator.OfInt) helper.wrapSpliterator(spliterator),
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   255
                            skip, limit, size);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   256
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   257
                else {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   258
                    return new SliceTask<>(this, helper, spliterator, Integer[]::new, skip, limit).
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   259
                            invoke().spliterator();
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   260
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   261
            }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   262
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   263
            @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   264
            <P_IN> Node<Integer> opEvaluateParallel(PipelineHelper<Integer> helper,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   265
                                                    Spliterator<P_IN> spliterator,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   266
                                                    IntFunction<Integer[]> generator) {
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   267
                long size = helper.exactOutputSizeIfKnown(spliterator);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   268
                if (size > 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   269
                    // Because the pipeline is SIZED the slice spliterator
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   270
                    // can be created from the source, this requires matching
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   271
                    // to shape of the source, and is potentially more efficient
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   272
                    // than creating the slice spliterator from the pipeline
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   273
                    // wrapping spliterator
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   274
                    Spliterator<P_IN> s = sliceSpliterator(helper.getSourceShape(), spliterator, skip, limit);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   275
                    return Nodes.collectInt(helper, s, true);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   276
                } else if (!StreamOpFlag.ORDERED.isKnown(helper.getStreamAndOpFlags())) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   277
                    Spliterator.OfInt s =  unorderedSkipLimitSpliterator(
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   278
                            (Spliterator.OfInt) helper.wrapSpliterator(spliterator),
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   279
                            skip, limit, size);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   280
                    // Collect using this pipeline, which is empty and therefore
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   281
                    // can be used with the pipeline wrapping spliterator
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   282
                    // Note that we cannot create a slice spliterator from
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   283
                    // the source spliterator if the pipeline is not SIZED
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   284
                    return Nodes.collectInt(this, s, true);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   285
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   286
                else {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   287
                    return new SliceTask<>(this, helper, spliterator, generator, skip, limit).
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   288
                            invoke();
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   289
                }
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   290
            }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   291
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   292
            @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   293
            Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   294
                return new Sink.ChainedInt(sink) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   295
                    long n = skip;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   296
                    long m = limit >= 0 ? limit : Long.MAX_VALUE;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   297
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   298
                    @Override
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   299
                    public void begin(long size) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   300
                        downstream.begin(calcSize(size, skip, m));
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   301
                    }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   302
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   303
                    @Override
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   304
                    public void accept(int t) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   305
                        if (n == 0) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   306
                            if (m > 0) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   307
                                m--;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   308
                                downstream.accept(t);
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   309
                            }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   310
                        }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   311
                        else {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   312
                            n--;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   313
                        }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   314
                    }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   315
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   316
                    @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   317
                    public boolean cancellationRequested() {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   318
                        return m == 0 || downstream.cancellationRequested();
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   319
                    }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   320
                };
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   321
            }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   322
        };
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   323
    }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   324
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   325
    /**
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   326
     * Appends a "slice" operation to the provided LongStream.  The slice
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   327
     * operation may be may be skip-only, limit-only, or skip-and-limit.
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   328
     *
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   329
     * @param upstream A LongStream
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   330
     * @param skip The number of elements to skip.  Must be >= 0.
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   331
     * @param limit The maximum size of the resulting stream, or -1 if no limit
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   332
     *        is to be imposed
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   333
     */
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   334
    public static LongStream makeLong(AbstractPipeline<?, Long, ?> upstream,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   335
                                      long skip, long limit) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   336
        if (skip < 0)
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   337
            throw new IllegalArgumentException("Skip must be non-negative: " + skip);
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   338
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   339
        return new LongPipeline.StatefulOp<Long>(upstream, StreamShape.LONG_VALUE,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   340
                                                 flags(limit)) {
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   341
            Spliterator.OfLong unorderedSkipLimitSpliterator(
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   342
                    Spliterator.OfLong s, long skip, long limit, long sizeIfKnown) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   343
                if (skip <= sizeIfKnown) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   344
                    // Use just the limit if the number of elements
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   345
                    // to skip is <= the known pipeline size
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   346
                    limit = limit >= 0 ? Math.min(limit, sizeIfKnown - skip) : sizeIfKnown - skip;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   347
                    skip = 0;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   348
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   349
                return new StreamSpliterators.UnorderedSliceSpliterator.OfLong(s, skip, limit);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   350
            }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   351
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   352
            @Override
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   353
            <P_IN> Spliterator<Long> opEvaluateParallelLazy(PipelineHelper<Long> helper,
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   354
                                                            Spliterator<P_IN> spliterator) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   355
                long size = helper.exactOutputSizeIfKnown(spliterator);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   356
                if (size > 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   357
                    return new StreamSpliterators.SliceSpliterator.OfLong(
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   358
                            (Spliterator.OfLong) helper.wrapSpliterator(spliterator),
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   359
                            skip,
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   360
                            calcSliceFence(skip, limit));
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   361
                } else if (!StreamOpFlag.ORDERED.isKnown(helper.getStreamAndOpFlags())) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   362
                    return unorderedSkipLimitSpliterator(
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   363
                            (Spliterator.OfLong) helper.wrapSpliterator(spliterator),
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   364
                            skip, limit, size);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   365
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   366
                else {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   367
                    return new SliceTask<>(this, helper, spliterator, Long[]::new, skip, limit).
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   368
                            invoke().spliterator();
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   369
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   370
            }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   371
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   372
            @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   373
            <P_IN> Node<Long> opEvaluateParallel(PipelineHelper<Long> helper,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   374
                                                 Spliterator<P_IN> spliterator,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   375
                                                 IntFunction<Long[]> generator) {
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   376
                long size = helper.exactOutputSizeIfKnown(spliterator);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   377
                if (size > 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   378
                    // Because the pipeline is SIZED the slice spliterator
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   379
                    // can be created from the source, this requires matching
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   380
                    // to shape of the source, and is potentially more efficient
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   381
                    // than creating the slice spliterator from the pipeline
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   382
                    // wrapping spliterator
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   383
                    Spliterator<P_IN> s = sliceSpliterator(helper.getSourceShape(), spliterator, skip, limit);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   384
                    return Nodes.collectLong(helper, s, true);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   385
                } else if (!StreamOpFlag.ORDERED.isKnown(helper.getStreamAndOpFlags())) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   386
                    Spliterator.OfLong s =  unorderedSkipLimitSpliterator(
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   387
                            (Spliterator.OfLong) helper.wrapSpliterator(spliterator),
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   388
                            skip, limit, size);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   389
                    // Collect using this pipeline, which is empty and therefore
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   390
                    // can be used with the pipeline wrapping spliterator
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   391
                    // Note that we cannot create a slice spliterator from
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   392
                    // the source spliterator if the pipeline is not SIZED
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   393
                    return Nodes.collectLong(this, s, true);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   394
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   395
                else {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   396
                    return new SliceTask<>(this, helper, spliterator, generator, skip, limit).
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   397
                            invoke();
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   398
                }
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   399
            }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   400
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   401
            @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   402
            Sink<Long> opWrapSink(int flags, Sink<Long> sink) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   403
                return new Sink.ChainedLong(sink) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   404
                    long n = skip;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   405
                    long m = limit >= 0 ? limit : Long.MAX_VALUE;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   406
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   407
                    @Override
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   408
                    public void begin(long size) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   409
                        downstream.begin(calcSize(size, skip, m));
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   410
                    }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   411
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   412
                    @Override
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   413
                    public void accept(long t) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   414
                        if (n == 0) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   415
                            if (m > 0) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   416
                                m--;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   417
                                downstream.accept(t);
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   418
                            }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   419
                        }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   420
                        else {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   421
                            n--;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   422
                        }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   423
                    }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   424
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   425
                    @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   426
                    public boolean cancellationRequested() {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   427
                        return m == 0 || downstream.cancellationRequested();
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   428
                    }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   429
                };
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   430
            }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   431
        };
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   432
    }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   433
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   434
    /**
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   435
     * Appends a "slice" operation to the provided DoubleStream.  The slice
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   436
     * operation may be may be skip-only, limit-only, or skip-and-limit.
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   437
     *
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   438
     * @param upstream A DoubleStream
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   439
     * @param skip The number of elements to skip.  Must be >= 0.
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   440
     * @param limit The maximum size of the resulting stream, or -1 if no limit
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   441
     *        is to be imposed
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   442
     */
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   443
    public static DoubleStream makeDouble(AbstractPipeline<?, Double, ?> upstream,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   444
                                          long skip, long limit) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   445
        if (skip < 0)
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   446
            throw new IllegalArgumentException("Skip must be non-negative: " + skip);
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   447
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   448
        return new DoublePipeline.StatefulOp<Double>(upstream, StreamShape.DOUBLE_VALUE,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   449
                                                     flags(limit)) {
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   450
            Spliterator.OfDouble unorderedSkipLimitSpliterator(
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   451
                    Spliterator.OfDouble s, long skip, long limit, long sizeIfKnown) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   452
                if (skip <= sizeIfKnown) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   453
                    // Use just the limit if the number of elements
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   454
                    // to skip is <= the known pipeline size
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   455
                    limit = limit >= 0 ? Math.min(limit, sizeIfKnown - skip) : sizeIfKnown - skip;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   456
                    skip = 0;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   457
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   458
                return new StreamSpliterators.UnorderedSliceSpliterator.OfDouble(s, skip, limit);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   459
            }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   460
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   461
            @Override
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   462
            <P_IN> Spliterator<Double> opEvaluateParallelLazy(PipelineHelper<Double> helper,
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   463
                                                              Spliterator<P_IN> spliterator) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   464
                long size = helper.exactOutputSizeIfKnown(spliterator);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   465
                if (size > 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   466
                    return new StreamSpliterators.SliceSpliterator.OfDouble(
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   467
                            (Spliterator.OfDouble) helper.wrapSpliterator(spliterator),
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   468
                            skip,
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   469
                            calcSliceFence(skip, limit));
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   470
                } else if (!StreamOpFlag.ORDERED.isKnown(helper.getStreamAndOpFlags())) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   471
                    return unorderedSkipLimitSpliterator(
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   472
                            (Spliterator.OfDouble) helper.wrapSpliterator(spliterator),
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   473
                            skip, limit, size);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   474
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   475
                else {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   476
                    return new SliceTask<>(this, helper, spliterator, Double[]::new, skip, limit).
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   477
                            invoke().spliterator();
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   478
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   479
            }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   480
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   481
            @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   482
            <P_IN> Node<Double> opEvaluateParallel(PipelineHelper<Double> helper,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   483
                                                   Spliterator<P_IN> spliterator,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   484
                                                   IntFunction<Double[]> generator) {
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   485
                long size = helper.exactOutputSizeIfKnown(spliterator);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   486
                if (size > 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   487
                    // Because the pipeline is SIZED the slice spliterator
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   488
                    // can be created from the source, this requires matching
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   489
                    // to shape of the source, and is potentially more efficient
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   490
                    // than creating the slice spliterator from the pipeline
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   491
                    // wrapping spliterator
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   492
                    Spliterator<P_IN> s = sliceSpliterator(helper.getSourceShape(), spliterator, skip, limit);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   493
                    return Nodes.collectDouble(helper, s, true);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   494
                } else if (!StreamOpFlag.ORDERED.isKnown(helper.getStreamAndOpFlags())) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   495
                    Spliterator.OfDouble s =  unorderedSkipLimitSpliterator(
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   496
                            (Spliterator.OfDouble) helper.wrapSpliterator(spliterator),
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   497
                            skip, limit, size);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   498
                    // Collect using this pipeline, which is empty and therefore
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   499
                    // can be used with the pipeline wrapping spliterator
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   500
                    // Note that we cannot create a slice spliterator from
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   501
                    // the source spliterator if the pipeline is not SIZED
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   502
                    return Nodes.collectDouble(this, s, true);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   503
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   504
                else {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   505
                    return new SliceTask<>(this, helper, spliterator, generator, skip, limit).
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   506
                            invoke();
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   507
                }
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   508
            }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   509
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   510
            @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   511
            Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   512
                return new Sink.ChainedDouble(sink) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   513
                    long n = skip;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   514
                    long m = limit >= 0 ? limit : Long.MAX_VALUE;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   515
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   516
                    @Override
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   517
                    public void begin(long size) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   518
                        downstream.begin(calcSize(size, skip, m));
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   519
                    }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   520
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   521
                    @Override
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   522
                    public void accept(double t) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   523
                        if (n == 0) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   524
                            if (m > 0) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   525
                                m--;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   526
                                downstream.accept(t);
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   527
                            }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   528
                        }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   529
                        else {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   530
                            n--;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   531
                        }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   532
                    }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   533
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   534
                    @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   535
                    public boolean cancellationRequested() {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   536
                        return m == 0 || downstream.cancellationRequested();
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   537
                    }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   538
                };
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   539
            }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   540
        };
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   541
    }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   542
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   543
    private static int flags(long limit) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   544
        return StreamOpFlag.NOT_SIZED | ((limit != -1) ? StreamOpFlag.IS_SHORT_CIRCUIT : 0);
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   545
    }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   546
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   547
    /**
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   548
     * {@code ForkJoinTask} implementing slice computation.
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   549
     *
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   550
     * @param <P_IN> Input element type to the stream pipeline
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   551
     * @param <P_OUT> Output element type from the stream pipeline
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   552
     */
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   553
    private static final class SliceTask<P_IN, P_OUT>
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   554
            extends AbstractShortCircuitTask<P_IN, P_OUT, Node<P_OUT>, SliceTask<P_IN, P_OUT>> {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   555
        private final AbstractPipeline<P_OUT, P_OUT, ?> op;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   556
        private final IntFunction<P_OUT[]> generator;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   557
        private final long targetOffset, targetSize;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   558
        private long thisNodeSize;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   559
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   560
        private volatile boolean completed;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   561
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   562
        SliceTask(AbstractPipeline<?, P_OUT, ?> op,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   563
                  PipelineHelper<P_OUT> helper,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   564
                  Spliterator<P_IN> spliterator,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   565
                  IntFunction<P_OUT[]> generator,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   566
                  long offset, long size) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   567
            super(helper, spliterator);
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   568
            this.op = (AbstractPipeline<P_OUT, P_OUT, ?>) op;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   569
            this.generator = generator;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   570
            this.targetOffset = offset;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   571
            this.targetSize = size;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   572
        }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   573
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   574
        SliceTask(SliceTask<P_IN, P_OUT> parent, Spliterator<P_IN> spliterator) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   575
            super(parent, spliterator);
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   576
            this.op = parent.op;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   577
            this.generator = parent.generator;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   578
            this.targetOffset = parent.targetOffset;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   579
            this.targetSize = parent.targetSize;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   580
        }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   581
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   582
        @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   583
        protected SliceTask<P_IN, P_OUT> makeChild(Spliterator<P_IN> spliterator) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   584
            return new SliceTask<>(this, spliterator);
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   585
        }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   586
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   587
        @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   588
        protected final Node<P_OUT> getEmptyResult() {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   589
            return Nodes.emptyNode(op.getOutputShape());
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   590
        }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   591
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   592
        @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   593
        protected final Node<P_OUT> doLeaf() {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   594
            if (isRoot()) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   595
                long sizeIfKnown = StreamOpFlag.SIZED.isPreserved(op.sourceOrOpFlags)
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   596
                                   ? op.exactOutputSizeIfKnown(spliterator)
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   597
                                   : -1;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   598
                final Node.Builder<P_OUT> nb = op.makeNodeBuilder(sizeIfKnown, generator);
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   599
                Sink<P_OUT> opSink = op.opWrapSink(helper.getStreamAndOpFlags(), nb);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   600
                helper.copyIntoWithCancel(helper.wrapSink(opSink), spliterator);
18770
b71393f8e3e4 8017329: 8b92-lambda regression: TreeSet("a", "b").stream().substream(1).parallel().iterator() is empty
psandoz
parents: 18572
diff changeset
   601
                // There is no need to truncate since the op performs the
b71393f8e3e4 8017329: 8b92-lambda regression: TreeSet("a", "b").stream().substream(1).parallel().iterator() is empty
psandoz
parents: 18572
diff changeset
   602
                // skipping and limiting of elements
b71393f8e3e4 8017329: 8b92-lambda regression: TreeSet("a", "b").stream().substream(1).parallel().iterator() is empty
psandoz
parents: 18572
diff changeset
   603
                return nb.build();
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   604
            }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   605
            else {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   606
                Node<P_OUT> node = helper.wrapAndCopyInto(helper.makeNodeBuilder(-1, generator),
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   607
                                                          spliterator).build();
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   608
                thisNodeSize = node.count();
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   609
                completed = true;
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   610
                spliterator = null;
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   611
                return node;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   612
            }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   613
        }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   614
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   615
        @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   616
        public final void onCompletion(CountedCompleter<?> caller) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   617
            if (!isLeaf()) {
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   618
                Node<P_OUT> result;
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   619
                thisNodeSize = leftChild.thisNodeSize + rightChild.thisNodeSize;
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   620
                if (canceled) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   621
                    thisNodeSize = 0;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   622
                    result = getEmptyResult();
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   623
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   624
                else if (thisNodeSize == 0)
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   625
                    result = getEmptyResult();
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   626
                else if (leftChild.thisNodeSize == 0)
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   627
                    result = rightChild.getLocalResult();
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   628
                else {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   629
                    result = Nodes.conc(op.getOutputShape(),
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   630
                                        leftChild.getLocalResult(), rightChild.getLocalResult());
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   631
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   632
                setLocalResult(isRoot() ? doTruncate(result) : result);
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   633
                completed = true;
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   634
            }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   635
            if (targetSize >= 0
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   636
                && !isRoot()
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   637
                && isLeftCompleted(targetOffset + targetSize))
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   638
                    cancelLaterNodes();
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   639
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   640
            super.onCompletion(caller);
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   641
        }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   642
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   643
        @Override
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   644
        protected void cancel() {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   645
            super.cancel();
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   646
            if (completed)
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   647
                setLocalResult(getEmptyResult());
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   648
        }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   649
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   650
        private Node<P_OUT> doTruncate(Node<P_OUT> input) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   651
            long to = targetSize >= 0 ? Math.min(input.count(), targetOffset + targetSize) : thisNodeSize;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   652
            return input.truncate(targetOffset, to, generator);
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   653
        }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   654
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   655
        /**
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   656
         * Determine if the number of completed elements in this node and nodes
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   657
         * to the left of this node is greater than or equal to the target size.
18527
882b39a21471 8016308: Updates to j.u.stream.Node/Nodes
psandoz
parents: 17182
diff changeset
   658
         *
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   659
         * @param target the target size
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   660
         * @return true if the number of elements is greater than or equal to
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   661
         *         the target size, otherwise false.
18527
882b39a21471 8016308: Updates to j.u.stream.Node/Nodes
psandoz
parents: 17182
diff changeset
   662
         */
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   663
        private boolean isLeftCompleted(long target) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   664
            long size = completed ? thisNodeSize : completedSize(target);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   665
            if (size >= target)
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   666
                return true;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   667
            for (SliceTask<P_IN, P_OUT> parent = getParent(), node = this;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   668
                 parent != null;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   669
                 node = parent, parent = parent.getParent()) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   670
                if (node == parent.rightChild) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   671
                    SliceTask<P_IN, P_OUT> left = parent.leftChild;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   672
                    if (left != null) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   673
                        size += left.completedSize(target);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   674
                        if (size >= target)
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   675
                            return true;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   676
                    }
18527
882b39a21471 8016308: Updates to j.u.stream.Node/Nodes
psandoz
parents: 17182
diff changeset
   677
                }
882b39a21471 8016308: Updates to j.u.stream.Node/Nodes
psandoz
parents: 17182
diff changeset
   678
            }
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   679
            return size >= target;
18527
882b39a21471 8016308: Updates to j.u.stream.Node/Nodes
psandoz
parents: 17182
diff changeset
   680
        }
882b39a21471 8016308: Updates to j.u.stream.Node/Nodes
psandoz
parents: 17182
diff changeset
   681
882b39a21471 8016308: Updates to j.u.stream.Node/Nodes
psandoz
parents: 17182
diff changeset
   682
        /**
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   683
         * Compute the number of completed elements in this node.
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   684
         * <p>
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   685
         * Computation terminates if all nodes have been processed or the
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   686
         * number of completed elements is greater than or equal to the target
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   687
         * size.
18527
882b39a21471 8016308: Updates to j.u.stream.Node/Nodes
psandoz
parents: 17182
diff changeset
   688
         *
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   689
         * @param target the target size
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   690
         * @return return the number of completed elements
18527
882b39a21471 8016308: Updates to j.u.stream.Node/Nodes
psandoz
parents: 17182
diff changeset
   691
         */
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   692
        private long completedSize(long target) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   693
            if (completed)
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   694
                return thisNodeSize;
18527
882b39a21471 8016308: Updates to j.u.stream.Node/Nodes
psandoz
parents: 17182
diff changeset
   695
            else {
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   696
                SliceTask<P_IN, P_OUT> left = leftChild;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   697
                SliceTask<P_IN, P_OUT> right = rightChild;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   698
                if (left == null || right == null) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   699
                    // must be completed
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   700
                    return thisNodeSize;
18527
882b39a21471 8016308: Updates to j.u.stream.Node/Nodes
psandoz
parents: 17182
diff changeset
   701
                }
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   702
                else {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   703
                    long leftSize = left.completedSize(target);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   704
                    return (leftSize >= target) ? leftSize : leftSize + right.completedSize(target);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   705
                }
18527
882b39a21471 8016308: Updates to j.u.stream.Node/Nodes
psandoz
parents: 17182
diff changeset
   706
            }
882b39a21471 8016308: Updates to j.u.stream.Node/Nodes
psandoz
parents: 17182
diff changeset
   707
        }
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   708
    }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   709
}