jdk/src/share/classes/java/util/stream/SliceOps.java
author psandoz
Thu, 16 Jan 2014 18:20:31 +0100
changeset 22289 bb9c71b84919
parent 19593 ce0cd954351c
child 25526 d3cbdae6e9f9
permissions -rw-r--r--
8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements Reviewed-by: mduigou, briangoetz
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
19593
ce0cd954351c 8023681: Fix raw type warning caused by Sink
henryjen
parents: 19218
diff changeset
    99
    @SuppressWarnings("unchecked")
ce0cd954351c 8023681: Fix raw type warning caused by Sink
henryjen
parents: 19218
diff changeset
   100
    private static <T> IntFunction<T[]> castingArray() {
ce0cd954351c 8023681: Fix raw type warning caused by Sink
henryjen
parents: 19218
diff changeset
   101
        return size -> (T[]) new Object[size];
ce0cd954351c 8023681: Fix raw type warning caused by Sink
henryjen
parents: 19218
diff changeset
   102
    }
ce0cd954351c 8023681: Fix raw type warning caused by Sink
henryjen
parents: 19218
diff changeset
   103
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   104
    /**
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   105
     * Appends a "slice" operation to the provided stream.  The slice operation
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   106
     * may be may be skip-only, limit-only, or skip-and-limit.
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   107
     *
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   108
     * @param <T> the type of both input and output elements
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   109
     * @param upstream a reference stream with element type T
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   110
     * @param skip the number of elements to skip.  Must be >= 0.
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   111
     * @param limit the maximum size of the resulting stream, or -1 if no limit
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   112
     *        is to be imposed
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   113
     */
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   114
    public static <T> Stream<T> makeRef(AbstractPipeline<?, T, ?> upstream,
19593
ce0cd954351c 8023681: Fix raw type warning caused by Sink
henryjen
parents: 19218
diff changeset
   115
                                        long skip, long limit) {
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   116
        if (skip < 0)
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   117
            throw new IllegalArgumentException("Skip must be non-negative: " + skip);
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   118
19593
ce0cd954351c 8023681: Fix raw type warning caused by Sink
henryjen
parents: 19218
diff changeset
   119
        return new ReferencePipeline.StatefulOp<T, T>(upstream, StreamShape.REFERENCE,
ce0cd954351c 8023681: Fix raw type warning caused by Sink
henryjen
parents: 19218
diff changeset
   120
                                                      flags(limit)) {
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   121
            Spliterator<T> unorderedSkipLimitSpliterator(Spliterator<T> s,
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   122
                                                         long skip, long limit, long sizeIfKnown) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   123
                if (skip <= sizeIfKnown) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   124
                    // Use just the limit if the number of elements
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   125
                    // to skip is <= the known pipeline size
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   126
                    limit = limit >= 0 ? Math.min(limit, sizeIfKnown - skip) : sizeIfKnown - skip;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   127
                    skip = 0;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   128
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   129
                return new StreamSpliterators.UnorderedSliceSpliterator.OfRef<>(s, skip, limit);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   130
            }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   131
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   132
            @Override
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   133
            <P_IN> Spliterator<T> opEvaluateParallelLazy(PipelineHelper<T> helper, Spliterator<P_IN> spliterator) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   134
                long size = helper.exactOutputSizeIfKnown(spliterator);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   135
                if (size > 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   136
                    return new StreamSpliterators.SliceSpliterator.OfRef<>(
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,
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   139
                            calcSliceFence(skip, limit));
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   140
                } else if (!StreamOpFlag.ORDERED.isKnown(helper.getStreamAndOpFlags())) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   141
                    return unorderedSkipLimitSpliterator(
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   142
                            helper.wrapSpliterator(spliterator),
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   143
                            skip, limit, size);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   144
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   145
                else {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   146
                    // @@@ OOMEs will occur for LongStream.longs().filter(i -> true).limit(n)
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   147
                    //     regardless of the value of n
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   148
                    //     Need to adjust the target size of splitting for the
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   149
                    //     SliceTask from say (size / k) to say min(size / k, 1 << 14)
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   150
                    //     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
   151
                    //     cancellation will be more aggressive cancelling later tasks
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   152
                    //     if the target slice size has been reached from a given task,
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   153
                    //     cancellation should also clear local results if any
19593
ce0cd954351c 8023681: Fix raw type warning caused by Sink
henryjen
parents: 19218
diff changeset
   154
                    return new SliceTask<>(this, helper, spliterator, castingArray(), skip, limit).
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   155
                            invoke().spliterator();
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   156
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   157
            }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   158
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   159
            @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   160
            <P_IN> Node<T> opEvaluateParallel(PipelineHelper<T> helper,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   161
                                              Spliterator<P_IN> spliterator,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   162
                                              IntFunction<T[]> generator) {
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   163
                long size = helper.exactOutputSizeIfKnown(spliterator);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   164
                if (size > 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   165
                    // Because the pipeline is SIZED the slice spliterator
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   166
                    // can be created from the source, this requires matching
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   167
                    // to shape of the source, and is potentially more efficient
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   168
                    // than creating the slice spliterator from the pipeline
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   169
                    // wrapping spliterator
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   170
                    Spliterator<P_IN> s = sliceSpliterator(helper.getSourceShape(), spliterator, skip, limit);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   171
                    return Nodes.collect(helper, s, true, generator);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   172
                } else if (!StreamOpFlag.ORDERED.isKnown(helper.getStreamAndOpFlags())) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   173
                    Spliterator<T> s =  unorderedSkipLimitSpliterator(
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   174
                            helper.wrapSpliterator(spliterator),
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   175
                            skip, limit, size);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   176
                    // Collect using this pipeline, which is empty and therefore
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   177
                    // can be used with the pipeline wrapping spliterator
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   178
                    // Note that we cannot create a slice spliterator from
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   179
                    // the source spliterator if the pipeline is not SIZED
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   180
                    return Nodes.collect(this, s, true, generator);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   181
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   182
                else {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   183
                    return new SliceTask<>(this, helper, spliterator, generator, skip, limit).
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   184
                            invoke();
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   185
                }
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   186
            }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   187
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   188
            @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   189
            Sink<T> opWrapSink(int flags, Sink<T> sink) {
19593
ce0cd954351c 8023681: Fix raw type warning caused by Sink
henryjen
parents: 19218
diff changeset
   190
                return new Sink.ChainedReference<T, T>(sink) {
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   191
                    long n = skip;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   192
                    long m = limit >= 0 ? limit : Long.MAX_VALUE;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   193
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   194
                    @Override
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   195
                    public void begin(long size) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   196
                        downstream.begin(calcSize(size, skip, m));
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   197
                    }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   198
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   199
                    @Override
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   200
                    public void accept(T t) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   201
                        if (n == 0) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   202
                            if (m > 0) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   203
                                m--;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   204
                                downstream.accept(t);
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
                        else {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   208
                            n--;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   209
                        }
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
                    @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   213
                    public boolean cancellationRequested() {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   214
                        return m == 0 || downstream.cancellationRequested();
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
            }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   218
        };
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   219
    }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   220
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   221
    /**
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   222
     * Appends a "slice" operation to the provided IntStream.  The slice
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   223
     * operation may be may be skip-only, limit-only, or skip-and-limit.
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   224
     *
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   225
     * @param upstream An IntStream
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   226
     * @param skip The number of elements to skip.  Must be >= 0.
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   227
     * @param limit The maximum size of the resulting stream, or -1 if no limit
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   228
     *        is to be imposed
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   229
     */
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   230
    public static IntStream makeInt(AbstractPipeline<?, Integer, ?> upstream,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   231
                                    long skip, long limit) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   232
        if (skip < 0)
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   233
            throw new IllegalArgumentException("Skip must be non-negative: " + skip);
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   234
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   235
        return new IntPipeline.StatefulOp<Integer>(upstream, StreamShape.INT_VALUE,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   236
                                                   flags(limit)) {
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   237
            Spliterator.OfInt unorderedSkipLimitSpliterator(
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   238
                    Spliterator.OfInt s, long skip, long limit, long sizeIfKnown) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   239
                if (skip <= sizeIfKnown) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   240
                    // Use just the limit if the number of elements
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   241
                    // to skip is <= the known pipeline size
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   242
                    limit = limit >= 0 ? Math.min(limit, sizeIfKnown - skip) : sizeIfKnown - skip;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   243
                    skip = 0;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   244
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   245
                return new StreamSpliterators.UnorderedSliceSpliterator.OfInt(s, skip, limit);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   246
            }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   247
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   248
            @Override
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   249
            <P_IN> Spliterator<Integer> opEvaluateParallelLazy(PipelineHelper<Integer> helper,
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   250
                                                               Spliterator<P_IN> spliterator) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   251
                long size = helper.exactOutputSizeIfKnown(spliterator);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   252
                if (size > 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   253
                    return new StreamSpliterators.SliceSpliterator.OfInt(
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,
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   256
                            calcSliceFence(skip, limit));
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   257
                } else if (!StreamOpFlag.ORDERED.isKnown(helper.getStreamAndOpFlags())) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   258
                    return unorderedSkipLimitSpliterator(
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   259
                            (Spliterator.OfInt) helper.wrapSpliterator(spliterator),
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   260
                            skip, limit, size);
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
                else {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   263
                    return new SliceTask<>(this, helper, spliterator, Integer[]::new, skip, limit).
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   264
                            invoke().spliterator();
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   265
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   266
            }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   267
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   268
            @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   269
            <P_IN> Node<Integer> opEvaluateParallel(PipelineHelper<Integer> helper,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   270
                                                    Spliterator<P_IN> spliterator,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   271
                                                    IntFunction<Integer[]> generator) {
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   272
                long size = helper.exactOutputSizeIfKnown(spliterator);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   273
                if (size > 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   274
                    // Because the pipeline is SIZED the slice spliterator
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   275
                    // can be created from the source, this requires matching
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   276
                    // to shape of the source, and is potentially more efficient
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   277
                    // than creating the slice spliterator from the pipeline
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   278
                    // wrapping spliterator
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   279
                    Spliterator<P_IN> s = sliceSpliterator(helper.getSourceShape(), spliterator, skip, limit);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   280
                    return Nodes.collectInt(helper, s, true);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   281
                } else if (!StreamOpFlag.ORDERED.isKnown(helper.getStreamAndOpFlags())) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   282
                    Spliterator.OfInt s =  unorderedSkipLimitSpliterator(
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   283
                            (Spliterator.OfInt) helper.wrapSpliterator(spliterator),
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   284
                            skip, limit, size);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   285
                    // Collect using this pipeline, which is empty and therefore
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   286
                    // can be used with the pipeline wrapping spliterator
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   287
                    // Note that we cannot create a slice spliterator from
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   288
                    // the source spliterator if the pipeline is not SIZED
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   289
                    return Nodes.collectInt(this, s, true);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   290
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   291
                else {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   292
                    return new SliceTask<>(this, helper, spliterator, generator, skip, limit).
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   293
                            invoke();
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   294
                }
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   295
            }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   296
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   297
            @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   298
            Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
19593
ce0cd954351c 8023681: Fix raw type warning caused by Sink
henryjen
parents: 19218
diff changeset
   299
                return new Sink.ChainedInt<Integer>(sink) {
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   300
                    long n = skip;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   301
                    long m = limit >= 0 ? limit : Long.MAX_VALUE;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   302
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   303
                    @Override
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   304
                    public void begin(long size) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   305
                        downstream.begin(calcSize(size, skip, m));
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   306
                    }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   307
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   308
                    @Override
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   309
                    public void accept(int t) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   310
                        if (n == 0) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   311
                            if (m > 0) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   312
                                m--;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   313
                                downstream.accept(t);
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
                        else {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   317
                            n--;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   318
                        }
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
                    @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   322
                    public boolean cancellationRequested() {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   323
                        return m == 0 || downstream.cancellationRequested();
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
            }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   327
        };
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   328
    }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   329
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   330
    /**
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   331
     * Appends a "slice" operation to the provided LongStream.  The slice
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   332
     * operation may be may be skip-only, limit-only, or skip-and-limit.
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   333
     *
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   334
     * @param upstream A LongStream
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   335
     * @param skip The number of elements to skip.  Must be >= 0.
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   336
     * @param limit The maximum size of the resulting stream, or -1 if no limit
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   337
     *        is to be imposed
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   338
     */
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   339
    public static LongStream makeLong(AbstractPipeline<?, Long, ?> upstream,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   340
                                      long skip, long limit) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   341
        if (skip < 0)
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   342
            throw new IllegalArgumentException("Skip must be non-negative: " + skip);
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   343
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   344
        return new LongPipeline.StatefulOp<Long>(upstream, StreamShape.LONG_VALUE,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   345
                                                 flags(limit)) {
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   346
            Spliterator.OfLong unorderedSkipLimitSpliterator(
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   347
                    Spliterator.OfLong s, long skip, long limit, long sizeIfKnown) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   348
                if (skip <= sizeIfKnown) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   349
                    // Use just the limit if the number of elements
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   350
                    // to skip is <= the known pipeline size
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   351
                    limit = limit >= 0 ? Math.min(limit, sizeIfKnown - skip) : sizeIfKnown - skip;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   352
                    skip = 0;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   353
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   354
                return new StreamSpliterators.UnorderedSliceSpliterator.OfLong(s, skip, limit);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   355
            }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   356
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   357
            @Override
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   358
            <P_IN> Spliterator<Long> opEvaluateParallelLazy(PipelineHelper<Long> helper,
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   359
                                                            Spliterator<P_IN> spliterator) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   360
                long size = helper.exactOutputSizeIfKnown(spliterator);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   361
                if (size > 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   362
                    return new StreamSpliterators.SliceSpliterator.OfLong(
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,
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   365
                            calcSliceFence(skip, limit));
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   366
                } else if (!StreamOpFlag.ORDERED.isKnown(helper.getStreamAndOpFlags())) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   367
                    return unorderedSkipLimitSpliterator(
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   368
                            (Spliterator.OfLong) helper.wrapSpliterator(spliterator),
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   369
                            skip, limit, size);
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
                else {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   372
                    return new SliceTask<>(this, helper, spliterator, Long[]::new, skip, limit).
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   373
                            invoke().spliterator();
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   374
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   375
            }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   376
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   377
            @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   378
            <P_IN> Node<Long> opEvaluateParallel(PipelineHelper<Long> helper,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   379
                                                 Spliterator<P_IN> spliterator,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   380
                                                 IntFunction<Long[]> generator) {
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   381
                long size = helper.exactOutputSizeIfKnown(spliterator);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   382
                if (size > 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   383
                    // Because the pipeline is SIZED the slice spliterator
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   384
                    // can be created from the source, this requires matching
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   385
                    // to shape of the source, and is potentially more efficient
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   386
                    // than creating the slice spliterator from the pipeline
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   387
                    // wrapping spliterator
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   388
                    Spliterator<P_IN> s = sliceSpliterator(helper.getSourceShape(), spliterator, skip, limit);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   389
                    return Nodes.collectLong(helper, s, true);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   390
                } else if (!StreamOpFlag.ORDERED.isKnown(helper.getStreamAndOpFlags())) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   391
                    Spliterator.OfLong s =  unorderedSkipLimitSpliterator(
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   392
                            (Spliterator.OfLong) helper.wrapSpliterator(spliterator),
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   393
                            skip, limit, size);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   394
                    // Collect using this pipeline, which is empty and therefore
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   395
                    // can be used with the pipeline wrapping spliterator
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   396
                    // Note that we cannot create a slice spliterator from
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   397
                    // the source spliterator if the pipeline is not SIZED
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   398
                    return Nodes.collectLong(this, s, true);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   399
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   400
                else {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   401
                    return new SliceTask<>(this, helper, spliterator, generator, skip, limit).
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   402
                            invoke();
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   403
                }
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   404
            }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   405
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   406
            @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   407
            Sink<Long> opWrapSink(int flags, Sink<Long> sink) {
19593
ce0cd954351c 8023681: Fix raw type warning caused by Sink
henryjen
parents: 19218
diff changeset
   408
                return new Sink.ChainedLong<Long>(sink) {
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   409
                    long n = skip;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   410
                    long m = limit >= 0 ? limit : Long.MAX_VALUE;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   411
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   412
                    @Override
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   413
                    public void begin(long size) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   414
                        downstream.begin(calcSize(size, skip, m));
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   415
                    }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   416
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   417
                    @Override
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   418
                    public void accept(long t) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   419
                        if (n == 0) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   420
                            if (m > 0) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   421
                                m--;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   422
                                downstream.accept(t);
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
                        else {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   426
                            n--;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   427
                        }
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
                    @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   431
                    public boolean cancellationRequested() {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   432
                        return m == 0 || downstream.cancellationRequested();
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
            }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   436
        };
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   437
    }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   438
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   439
    /**
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   440
     * Appends a "slice" operation to the provided DoubleStream.  The slice
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   441
     * operation may be may be skip-only, limit-only, or skip-and-limit.
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   442
     *
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   443
     * @param upstream A DoubleStream
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   444
     * @param skip The number of elements to skip.  Must be >= 0.
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   445
     * @param limit The maximum size of the resulting stream, or -1 if no limit
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   446
     *        is to be imposed
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   447
     */
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   448
    public static DoubleStream makeDouble(AbstractPipeline<?, Double, ?> upstream,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   449
                                          long skip, long limit) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   450
        if (skip < 0)
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   451
            throw new IllegalArgumentException("Skip must be non-negative: " + skip);
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   452
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   453
        return new DoublePipeline.StatefulOp<Double>(upstream, StreamShape.DOUBLE_VALUE,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   454
                                                     flags(limit)) {
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   455
            Spliterator.OfDouble unorderedSkipLimitSpliterator(
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   456
                    Spliterator.OfDouble s, long skip, long limit, long sizeIfKnown) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   457
                if (skip <= sizeIfKnown) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   458
                    // Use just the limit if the number of elements
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   459
                    // to skip is <= the known pipeline size
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   460
                    limit = limit >= 0 ? Math.min(limit, sizeIfKnown - skip) : sizeIfKnown - skip;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   461
                    skip = 0;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   462
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   463
                return new StreamSpliterators.UnorderedSliceSpliterator.OfDouble(s, skip, limit);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   464
            }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   465
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   466
            @Override
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   467
            <P_IN> Spliterator<Double> opEvaluateParallelLazy(PipelineHelper<Double> helper,
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   468
                                                              Spliterator<P_IN> spliterator) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   469
                long size = helper.exactOutputSizeIfKnown(spliterator);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   470
                if (size > 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   471
                    return new StreamSpliterators.SliceSpliterator.OfDouble(
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,
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   474
                            calcSliceFence(skip, limit));
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   475
                } else if (!StreamOpFlag.ORDERED.isKnown(helper.getStreamAndOpFlags())) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   476
                    return unorderedSkipLimitSpliterator(
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   477
                            (Spliterator.OfDouble) helper.wrapSpliterator(spliterator),
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   478
                            skip, limit, size);
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
                else {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   481
                    return new SliceTask<>(this, helper, spliterator, Double[]::new, skip, limit).
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   482
                            invoke().spliterator();
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   483
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   484
            }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   485
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   486
            @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   487
            <P_IN> Node<Double> opEvaluateParallel(PipelineHelper<Double> helper,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   488
                                                   Spliterator<P_IN> spliterator,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   489
                                                   IntFunction<Double[]> generator) {
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   490
                long size = helper.exactOutputSizeIfKnown(spliterator);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   491
                if (size > 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   492
                    // Because the pipeline is SIZED the slice spliterator
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   493
                    // can be created from the source, this requires matching
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   494
                    // to shape of the source, and is potentially more efficient
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   495
                    // than creating the slice spliterator from the pipeline
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   496
                    // wrapping spliterator
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   497
                    Spliterator<P_IN> s = sliceSpliterator(helper.getSourceShape(), spliterator, skip, limit);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   498
                    return Nodes.collectDouble(helper, s, true);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   499
                } else if (!StreamOpFlag.ORDERED.isKnown(helper.getStreamAndOpFlags())) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   500
                    Spliterator.OfDouble s =  unorderedSkipLimitSpliterator(
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   501
                            (Spliterator.OfDouble) helper.wrapSpliterator(spliterator),
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   502
                            skip, limit, size);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   503
                    // Collect using this pipeline, which is empty and therefore
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   504
                    // can be used with the pipeline wrapping spliterator
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   505
                    // Note that we cannot create a slice spliterator from
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   506
                    // the source spliterator if the pipeline is not SIZED
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   507
                    return Nodes.collectDouble(this, s, true);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   508
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   509
                else {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   510
                    return new SliceTask<>(this, helper, spliterator, generator, skip, limit).
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   511
                            invoke();
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   512
                }
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   513
            }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   514
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   515
            @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   516
            Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
19593
ce0cd954351c 8023681: Fix raw type warning caused by Sink
henryjen
parents: 19218
diff changeset
   517
                return new Sink.ChainedDouble<Double>(sink) {
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   518
                    long n = skip;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   519
                    long m = limit >= 0 ? limit : Long.MAX_VALUE;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   520
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   521
                    @Override
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   522
                    public void begin(long size) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   523
                        downstream.begin(calcSize(size, skip, m));
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   524
                    }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   525
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   526
                    @Override
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   527
                    public void accept(double t) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   528
                        if (n == 0) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   529
                            if (m > 0) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   530
                                m--;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   531
                                downstream.accept(t);
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
                        else {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   535
                            n--;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   536
                        }
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
                    @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   540
                    public boolean cancellationRequested() {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   541
                        return m == 0 || downstream.cancellationRequested();
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   542
                    }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   543
                };
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   544
            }
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
    private static int flags(long limit) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   549
        return StreamOpFlag.NOT_SIZED | ((limit != -1) ? StreamOpFlag.IS_SHORT_CIRCUIT : 0);
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   550
    }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   551
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   552
    /**
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   553
     * {@code ForkJoinTask} implementing slice computation.
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   554
     *
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   555
     * @param <P_IN> Input element type to the stream pipeline
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   556
     * @param <P_OUT> Output element type from the stream pipeline
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   557
     */
19218
8e7212b90b81 8022446: Fix serial warnings in java.util.stream
henryjen
parents: 18770
diff changeset
   558
    @SuppressWarnings("serial")
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   559
    private static final class SliceTask<P_IN, P_OUT>
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   560
            extends AbstractShortCircuitTask<P_IN, P_OUT, Node<P_OUT>, SliceTask<P_IN, P_OUT>> {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   561
        private final AbstractPipeline<P_OUT, P_OUT, ?> op;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   562
        private final IntFunction<P_OUT[]> generator;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   563
        private final long targetOffset, targetSize;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   564
        private long thisNodeSize;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   565
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   566
        private volatile boolean completed;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   567
19593
ce0cd954351c 8023681: Fix raw type warning caused by Sink
henryjen
parents: 19218
diff changeset
   568
        SliceTask(AbstractPipeline<P_OUT, P_OUT, ?> op,
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   569
                  PipelineHelper<P_OUT> helper,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   570
                  Spliterator<P_IN> spliterator,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   571
                  IntFunction<P_OUT[]> generator,
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   572
                  long offset, long size) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   573
            super(helper, spliterator);
19593
ce0cd954351c 8023681: Fix raw type warning caused by Sink
henryjen
parents: 19218
diff changeset
   574
            this.op = op;
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   575
            this.generator = generator;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   576
            this.targetOffset = offset;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   577
            this.targetSize = size;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   578
        }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   579
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   580
        SliceTask(SliceTask<P_IN, P_OUT> parent, Spliterator<P_IN> spliterator) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   581
            super(parent, spliterator);
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   582
            this.op = parent.op;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   583
            this.generator = parent.generator;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   584
            this.targetOffset = parent.targetOffset;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   585
            this.targetSize = parent.targetSize;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   586
        }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   587
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   588
        @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   589
        protected SliceTask<P_IN, P_OUT> makeChild(Spliterator<P_IN> spliterator) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   590
            return new SliceTask<>(this, spliterator);
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   591
        }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   592
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   593
        @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   594
        protected final Node<P_OUT> getEmptyResult() {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   595
            return Nodes.emptyNode(op.getOutputShape());
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   596
        }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   597
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   598
        @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   599
        protected final Node<P_OUT> doLeaf() {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   600
            if (isRoot()) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   601
                long sizeIfKnown = StreamOpFlag.SIZED.isPreserved(op.sourceOrOpFlags)
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   602
                                   ? op.exactOutputSizeIfKnown(spliterator)
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   603
                                   : -1;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   604
                final Node.Builder<P_OUT> nb = op.makeNodeBuilder(sizeIfKnown, generator);
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   605
                Sink<P_OUT> opSink = op.opWrapSink(helper.getStreamAndOpFlags(), nb);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   606
                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
   607
                // 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
   608
                // 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
   609
                return nb.build();
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   610
            }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   611
            else {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   612
                Node<P_OUT> node = helper.wrapAndCopyInto(helper.makeNodeBuilder(-1, generator),
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   613
                                                          spliterator).build();
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   614
                thisNodeSize = node.count();
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   615
                completed = true;
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   616
                spliterator = null;
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   617
                return node;
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   618
            }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   619
        }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   620
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   621
        @Override
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   622
        public final void onCompletion(CountedCompleter<?> caller) {
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   623
            if (!isLeaf()) {
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   624
                Node<P_OUT> result;
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   625
                thisNodeSize = leftChild.thisNodeSize + rightChild.thisNodeSize;
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   626
                if (canceled) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   627
                    thisNodeSize = 0;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   628
                    result = getEmptyResult();
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   629
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   630
                else if (thisNodeSize == 0)
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   631
                    result = getEmptyResult();
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   632
                else if (leftChild.thisNodeSize == 0)
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   633
                    result = rightChild.getLocalResult();
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   634
                else {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   635
                    result = Nodes.conc(op.getOutputShape(),
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   636
                                        leftChild.getLocalResult(), rightChild.getLocalResult());
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   637
                }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   638
                setLocalResult(isRoot() ? doTruncate(result) : result);
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   639
                completed = true;
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   640
            }
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   641
            if (targetSize >= 0
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   642
                && !isRoot()
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   643
                && isLeftCompleted(targetOffset + targetSize))
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   644
                    cancelLaterNodes();
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   645
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   646
            super.onCompletion(caller);
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   647
        }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   648
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   649
        @Override
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   650
        protected void cancel() {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   651
            super.cancel();
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   652
            if (completed)
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   653
                setLocalResult(getEmptyResult());
17182
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
        private Node<P_OUT> doTruncate(Node<P_OUT> input) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   657
            long to = targetSize >= 0 ? Math.min(input.count(), targetOffset + targetSize) : thisNodeSize;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   658
            return input.truncate(targetOffset, to, generator);
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   659
        }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   660
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   661
        /**
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   662
         * Determine if the number of completed elements in this node and nodes
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   663
         * 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
   664
         *
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   665
         * @param target the target size
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   666
         * @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
   667
         *         the target size, otherwise false.
18527
882b39a21471 8016308: Updates to j.u.stream.Node/Nodes
psandoz
parents: 17182
diff changeset
   668
         */
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   669
        private boolean isLeftCompleted(long target) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   670
            long size = completed ? thisNodeSize : completedSize(target);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   671
            if (size >= target)
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   672
                return true;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   673
            for (SliceTask<P_IN, P_OUT> parent = getParent(), node = this;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   674
                 parent != null;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   675
                 node = parent, parent = parent.getParent()) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   676
                if (node == parent.rightChild) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   677
                    SliceTask<P_IN, P_OUT> left = parent.leftChild;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   678
                    if (left != null) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   679
                        size += left.completedSize(target);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   680
                        if (size >= target)
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   681
                            return true;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   682
                    }
18527
882b39a21471 8016308: Updates to j.u.stream.Node/Nodes
psandoz
parents: 17182
diff changeset
   683
                }
882b39a21471 8016308: Updates to j.u.stream.Node/Nodes
psandoz
parents: 17182
diff changeset
   684
            }
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   685
            return size >= target;
18527
882b39a21471 8016308: Updates to j.u.stream.Node/Nodes
psandoz
parents: 17182
diff changeset
   686
        }
882b39a21471 8016308: Updates to j.u.stream.Node/Nodes
psandoz
parents: 17182
diff changeset
   687
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
         * Compute the number of completed elements in this node.
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   690
         * <p>
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   691
         * Computation terminates if all nodes have been processed or the
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   692
         * number of completed elements is greater than or equal to the target
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   693
         * size.
18527
882b39a21471 8016308: Updates to j.u.stream.Node/Nodes
psandoz
parents: 17182
diff changeset
   694
         *
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   695
         * @param target the target size
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   696
         * @return return the number of completed elements
18527
882b39a21471 8016308: Updates to j.u.stream.Node/Nodes
psandoz
parents: 17182
diff changeset
   697
         */
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   698
        private long completedSize(long target) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   699
            if (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
            else {
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   702
                SliceTask<P_IN, P_OUT> left = leftChild;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   703
                SliceTask<P_IN, P_OUT> right = rightChild;
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   704
                if (left == null || right == null) {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   705
                    // must be completed
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   706
                    return thisNodeSize;
18527
882b39a21471 8016308: Updates to j.u.stream.Node/Nodes
psandoz
parents: 17182
diff changeset
   707
                }
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   708
                else {
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   709
                    long leftSize = left.completedSize(target);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   710
                    return (leftSize >= target) ? leftSize : leftSize + right.completedSize(target);
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 18527
diff changeset
   711
                }
18527
882b39a21471 8016308: Updates to j.u.stream.Node/Nodes
psandoz
parents: 17182
diff changeset
   712
            }
882b39a21471 8016308: Updates to j.u.stream.Node/Nodes
psandoz
parents: 17182
diff changeset
   713
        }
17182
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   714
    }
b786c0de868c 8011920: Main streams implementation
mduigou
parents:
diff changeset
   715
}