jdk/src/share/classes/java/util/stream/ForEachOps.java
author psandoz
Thu, 16 Jan 2014 18:20:31 +0100
changeset 22289 bb9c71b84919
parent 19218 8e7212b90b81
child 22297 1c62c67d9dd2
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:
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
     1
/*
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
     2
 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
     4
 *
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    10
 *
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    15
 * accompanied this code).
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    16
 *
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    20
 *
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    23
 * questions.
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    24
 */
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    25
package java.util.stream;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    26
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    27
import java.util.Objects;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    28
import java.util.Spliterator;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    29
import java.util.concurrent.ConcurrentHashMap;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    30
import java.util.concurrent.CountedCompleter;
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
    31
import java.util.concurrent.ForkJoinTask;
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    32
import java.util.function.Consumer;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    33
import java.util.function.DoubleConsumer;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    34
import java.util.function.IntConsumer;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    35
import java.util.function.LongConsumer;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    36
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    37
/**
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    38
 * Factory for creating instances of {@code TerminalOp} that perform an
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    39
 * action for every element of a stream.  Supported variants include unordered
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    40
 * traversal (elements are provided to the {@code Consumer} as soon as they are
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    41
 * available), and ordered traversal (elements are provided to the
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    42
 * {@code Consumer} in encounter order.)
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    43
 *
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    44
 * <p>Elements are provided to the {@code Consumer} on whatever thread and
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    45
 * whatever order they become available.  For ordered traversals, it is
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    46
 * guaranteed that processing an element <em>happens-before</em> processing
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    47
 * subsequent elements in the encounter order.
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    48
 *
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    49
 * <p>Exceptions occurring as a result of sending an element to the
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    50
 * {@code Consumer} will be relayed to the caller and traversal will be
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    51
 * prematurely terminated.
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    52
 *
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    53
 * @since 1.8
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    54
 */
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    55
final class ForEachOps {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    56
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    57
    private ForEachOps() { }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    58
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    59
    /**
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    60
     * Constructs a {@code TerminalOp} that perform an action for every element
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    61
     * of a stream.
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    62
     *
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    63
     * @param action the {@code Consumer} that receives all elements of a
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    64
     *        stream
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    65
     * @param ordered whether an ordered traversal is requested
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    66
     * @param <T> the type of the stream elements
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    67
     * @return the {@code TerminalOp} instance
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    68
     */
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    69
    public static <T> TerminalOp<T, Void> makeRef(Consumer<? super T> action,
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    70
                                                  boolean ordered) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    71
        Objects.requireNonNull(action);
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    72
        return new ForEachOp.OfRef<>(action, ordered);
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    73
    }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    74
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    75
    /**
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    76
     * Constructs a {@code TerminalOp} that perform an action for every element
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    77
     * of an {@code IntStream}.
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    78
     *
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    79
     * @param action the {@code IntConsumer} that receives all elements of a
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    80
     *        stream
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    81
     * @param ordered whether an ordered traversal is requested
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    82
     * @return the {@code TerminalOp} instance
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    83
     */
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    84
    public static TerminalOp<Integer, Void> makeInt(IntConsumer action,
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    85
                                                    boolean ordered) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    86
        Objects.requireNonNull(action);
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    87
        return new ForEachOp.OfInt(action, ordered);
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    88
    }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    89
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    90
    /**
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    91
     * Constructs a {@code TerminalOp} that perform an action for every element
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    92
     * of a {@code LongStream}.
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    93
     *
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    94
     * @param action the {@code LongConsumer} that receives all elements of a
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    95
     *        stream
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    96
     * @param ordered whether an ordered traversal is requested
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    97
     * @return the {@code TerminalOp} instance
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    98
     */
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    99
    public static TerminalOp<Long, Void> makeLong(LongConsumer action,
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   100
                                                  boolean ordered) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   101
        Objects.requireNonNull(action);
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   102
        return new ForEachOp.OfLong(action, ordered);
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   103
    }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   104
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   105
    /**
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   106
     * Constructs a {@code TerminalOp} that perform an action for every element
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   107
     * of a {@code DoubleStream}.
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   108
     *
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   109
     * @param action the {@code DoubleConsumer} that receives all elements of
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   110
     *        a stream
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   111
     * @param ordered whether an ordered traversal is requested
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   112
     * @return the {@code TerminalOp} instance
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   113
     */
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   114
    public static TerminalOp<Double, Void> makeDouble(DoubleConsumer action,
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   115
                                                      boolean ordered) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   116
        Objects.requireNonNull(action);
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   117
        return new ForEachOp.OfDouble(action, ordered);
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   118
    }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   119
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   120
    /**
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   121
     * A {@code TerminalOp} that evaluates a stream pipeline and sends the
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   122
     * output to itself as a {@code TerminalSink}.  Elements will be sent in
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   123
     * whatever thread they become available.  If the traversal is unordered,
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   124
     * they will be sent independent of the stream's encounter order.
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   125
     *
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   126
     * <p>This terminal operation is stateless.  For parallel evaluation, each
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   127
     * leaf instance of a {@code ForEachTask} will send elements to the same
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   128
     * {@code TerminalSink} reference that is an instance of this class.
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   129
     *
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   130
     * @param <T> the output type of the stream pipeline
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   131
     */
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   132
    static abstract class ForEachOp<T>
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   133
            implements TerminalOp<T, Void>, TerminalSink<T, Void> {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   134
        private final boolean ordered;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   135
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   136
        protected ForEachOp(boolean ordered) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   137
            this.ordered = ordered;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   138
        }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   139
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   140
        // TerminalOp
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   141
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   142
        @Override
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   143
        public int getOpFlags() {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   144
            return ordered ? 0 : StreamOpFlag.NOT_ORDERED;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   145
        }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   146
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   147
        @Override
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   148
        public <S> Void evaluateSequential(PipelineHelper<T> helper,
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   149
                                           Spliterator<S> spliterator) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   150
            return helper.wrapAndCopyInto(this, spliterator).get();
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   151
        }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   152
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   153
        @Override
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   154
        public <S> Void evaluateParallel(PipelineHelper<T> helper,
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   155
                                         Spliterator<S> spliterator) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   156
            if (ordered)
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   157
                new ForEachOrderedTask<>(helper, spliterator, this).invoke();
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   158
            else
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   159
                new ForEachTask<>(helper, spliterator, helper.wrapSink(this)).invoke();
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   160
            return null;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   161
        }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   162
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   163
        // TerminalSink
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   164
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   165
        @Override
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   166
        public Void get() {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   167
            return null;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   168
        }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   169
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   170
        // Implementations
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   171
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   172
        /** Implementation class for reference streams */
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   173
        static final class OfRef<T> extends ForEachOp<T> {
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   174
            final Consumer<? super T> consumer;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   175
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   176
            OfRef(Consumer<? super T> consumer, boolean ordered) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   177
                super(ordered);
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   178
                this.consumer = consumer;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   179
            }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   180
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   181
            @Override
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   182
            public void accept(T t) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   183
                consumer.accept(t);
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   184
            }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   185
        }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   186
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   187
        /** Implementation class for {@code IntStream} */
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   188
        static final class OfInt extends ForEachOp<Integer>
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   189
                implements Sink.OfInt {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   190
            final IntConsumer consumer;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   191
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   192
            OfInt(IntConsumer consumer, boolean ordered) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   193
                super(ordered);
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   194
                this.consumer = consumer;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   195
            }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   196
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   197
            @Override
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   198
            public StreamShape inputShape() {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   199
                return StreamShape.INT_VALUE;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   200
            }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   201
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   202
            @Override
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   203
            public void accept(int t) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   204
                consumer.accept(t);
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   205
            }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   206
        }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   207
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   208
        /** Implementation class for {@code LongStream} */
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   209
        static final class OfLong extends ForEachOp<Long>
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   210
                implements Sink.OfLong {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   211
            final LongConsumer consumer;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   212
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   213
            OfLong(LongConsumer consumer, boolean ordered) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   214
                super(ordered);
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   215
                this.consumer = consumer;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   216
            }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   217
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   218
            @Override
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   219
            public StreamShape inputShape() {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   220
                return StreamShape.LONG_VALUE;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   221
            }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   222
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   223
            @Override
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   224
            public void accept(long t) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   225
                consumer.accept(t);
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   226
            }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   227
        }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   228
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   229
        /** Implementation class for {@code DoubleStream} */
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   230
        static final class OfDouble extends ForEachOp<Double>
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   231
                implements Sink.OfDouble {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   232
            final DoubleConsumer consumer;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   233
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   234
            OfDouble(DoubleConsumer consumer, boolean ordered) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   235
                super(ordered);
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   236
                this.consumer = consumer;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   237
            }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   238
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   239
            @Override
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   240
            public StreamShape inputShape() {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   241
                return StreamShape.DOUBLE_VALUE;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   242
            }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   243
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   244
            @Override
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   245
            public void accept(double t) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   246
                consumer.accept(t);
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   247
            }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   248
        }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   249
    }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   250
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   251
    /** A {@code ForkJoinTask} for performing a parallel for-each operation */
19218
8e7212b90b81 8022446: Fix serial warnings in java.util.stream
henryjen
parents: 18795
diff changeset
   252
    @SuppressWarnings("serial")
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   253
    static final class ForEachTask<S, T> extends CountedCompleter<Void> {
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   254
        private Spliterator<S> spliterator;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   255
        private final Sink<S> sink;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   256
        private final PipelineHelper<T> helper;
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   257
        private long targetSize;
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   258
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   259
        ForEachTask(PipelineHelper<T> helper,
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   260
                    Spliterator<S> spliterator,
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   261
                    Sink<S> sink) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   262
            super(null);
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   263
            this.sink = sink;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   264
            this.helper = helper;
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   265
            this.spliterator = spliterator;
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   266
            this.targetSize = 0L;
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   267
        }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   268
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   269
        ForEachTask(ForEachTask<S, T> parent, Spliterator<S> spliterator) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   270
            super(parent);
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   271
            this.spliterator = spliterator;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   272
            this.sink = parent.sink;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   273
            this.targetSize = parent.targetSize;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   274
            this.helper = parent.helper;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   275
        }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   276
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   277
        // Similar to AbstractTask but doesn't need to track child tasks
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   278
        public void compute() {
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   279
            Spliterator<S> rightSplit = spliterator, leftSplit;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   280
            long sizeEstimate = rightSplit.estimateSize(), sizeThreshold;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   281
            if ((sizeThreshold = targetSize) == 0L)
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   282
                targetSize = sizeThreshold = AbstractTask.suggestTargetSize(sizeEstimate);
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   283
            boolean isShortCircuit = StreamOpFlag.SHORT_CIRCUIT.isKnown(helper.getStreamAndOpFlags());
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   284
            boolean forkRight = false;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   285
            Sink<S> taskSink = sink;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   286
            ForEachTask<S, T> task = this;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   287
            while (!isShortCircuit || !taskSink.cancellationRequested()) {
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   288
                if (sizeEstimate <= sizeThreshold ||
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   289
                    (leftSplit = rightSplit.trySplit()) == null) {
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   290
                    task.helper.copyInto(taskSink, rightSplit);
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   291
                    break;
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   292
                }
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   293
                ForEachTask<S, T> leftTask = new ForEachTask<>(task, leftSplit);
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   294
                task.addToPendingCount(1);
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   295
                ForEachTask<S, T> taskToFork;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   296
                if (forkRight) {
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   297
                    forkRight = false;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   298
                    rightSplit = leftSplit;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   299
                    taskToFork = task;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   300
                    task = leftTask;
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   301
                }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   302
                else {
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   303
                    forkRight = true;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   304
                    taskToFork = leftTask;
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   305
                }
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   306
                taskToFork.fork();
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   307
                sizeEstimate = rightSplit.estimateSize();
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   308
            }
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   309
            task.spliterator = null;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   310
            task.propagateCompletion();
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   311
        }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   312
    }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   313
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   314
    /**
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   315
     * A {@code ForkJoinTask} for performing a parallel for-each operation
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   316
     * which visits the elements in encounter order
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   317
     */
19218
8e7212b90b81 8022446: Fix serial warnings in java.util.stream
henryjen
parents: 18795
diff changeset
   318
    @SuppressWarnings("serial")
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   319
    static final class ForEachOrderedTask<S, T> extends CountedCompleter<Void> {
22289
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   320
        /*
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   321
         * Our goal is to ensure that the elements associated with a task are
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   322
         * processed according to an in-order traversal of the computation tree.
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   323
         * We use completion counts for representing these dependencies, so that
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   324
         * a task does not complete until all the tasks preceding it in this
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   325
         * order complete.  We use the "completion map" to associate the next
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   326
         * task in this order for any left child.  We increase the pending count
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   327
         * of any node on the right side of such a mapping by one to indicate
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   328
         * its dependency, and when a node on the left side of such a mapping
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   329
         * completes, it decrements the pending count of its corresponding right
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   330
         * side.  As the computation tree is expanded by splitting, we must
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   331
         * atomically update the mappings to maintain the invariant that the
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   332
         * completion map maps left children to the next node in the in-order
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   333
         * traversal.
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   334
         *
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   335
         * Take, for example, the following computation tree of tasks:
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   336
         *
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   337
         *       a
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   338
         *      / \
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   339
         *     b   c
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   340
         *    / \ / \
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   341
         *   d  e f  g
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   342
         *
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   343
         * The complete map will contain (not necessarily all at the same time)
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   344
         * the following associations:
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   345
         *
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   346
         *   d -> e
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   347
         *   b -> f
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   348
         *   f -> g
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   349
         *
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   350
         * Tasks e, f, g will have their pending counts increased by 1.
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   351
         *
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   352
         * The following relationships hold:
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   353
         *
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   354
         *   - completion of d "happens-before" e;
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   355
         *   - completion of d and e "happens-before b;
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   356
         *   - completion of b "happens-before" f; and
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   357
         *   - completion of f "happens-before" g
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   358
         *
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   359
         * Thus overall the "happens-before" relationship holds for the
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   360
         * reporting of elements, covered by tasks d, e, f and g, as specified
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   361
         * by the forEachOrdered operation.
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   362
         */
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   363
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   364
        private final PipelineHelper<T> helper;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   365
        private Spliterator<S> spliterator;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   366
        private final long targetSize;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   367
        private final ConcurrentHashMap<ForEachOrderedTask<S, T>, ForEachOrderedTask<S, T>> completionMap;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   368
        private final Sink<T> action;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   369
        private final ForEachOrderedTask<S, T> leftPredecessor;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   370
        private Node<T> node;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   371
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   372
        protected ForEachOrderedTask(PipelineHelper<T> helper,
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   373
                                     Spliterator<S> spliterator,
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   374
                                     Sink<T> action) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   375
            super(null);
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   376
            this.helper = helper;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   377
            this.spliterator = spliterator;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   378
            this.targetSize = AbstractTask.suggestTargetSize(spliterator.estimateSize());
22289
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   379
            // Size map to avoid concurrent re-sizes
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   380
            this.completionMap = new ConcurrentHashMap<>(Math.max(16, AbstractTask.LEAF_TARGET << 1));
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   381
            this.action = action;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   382
            this.leftPredecessor = null;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   383
        }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   384
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   385
        ForEachOrderedTask(ForEachOrderedTask<S, T> parent,
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   386
                           Spliterator<S> spliterator,
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   387
                           ForEachOrderedTask<S, T> leftPredecessor) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   388
            super(parent);
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   389
            this.helper = parent.helper;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   390
            this.spliterator = spliterator;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   391
            this.targetSize = parent.targetSize;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   392
            this.completionMap = parent.completionMap;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   393
            this.action = parent.action;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   394
            this.leftPredecessor = leftPredecessor;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   395
        }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   396
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   397
        @Override
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   398
        public final void compute() {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   399
            doCompute(this);
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   400
        }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   401
18572
53b8b8c30086 8012987: Optimizations for Stream.limit/substream
psandoz
parents: 17163
diff changeset
   402
        private static <S, T> void doCompute(ForEachOrderedTask<S, T> task) {
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   403
            Spliterator<S> rightSplit = task.spliterator, leftSplit;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   404
            long sizeThreshold = task.targetSize;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   405
            boolean forkRight = false;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   406
            while (rightSplit.estimateSize() > sizeThreshold &&
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   407
                   (leftSplit = rightSplit.trySplit()) != null) {
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   408
                ForEachOrderedTask<S, T> leftChild =
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   409
                    new ForEachOrderedTask<>(task, leftSplit, task.leftPredecessor);
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   410
                ForEachOrderedTask<S, T> rightChild =
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   411
                    new ForEachOrderedTask<>(task, rightSplit, leftChild);
22289
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   412
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   413
                // Fork the parent task
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   414
                // Completion of the left and right children "happens-before"
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   415
                // completion of the parent
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   416
                task.addToPendingCount(1);
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   417
                // Completion of the left child "happens-before" completion of
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   418
                // the right child
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   419
                rightChild.addToPendingCount(1);
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   420
                task.completionMap.put(leftChild, rightChild);
22289
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   421
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   422
                // If task is not on the left spine
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   423
                if (task.leftPredecessor != null) {
22289
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   424
                    /*
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   425
                     * Completion of left-predecessor, or left subtree,
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   426
                     * "happens-before" completion of left-most leaf node of
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   427
                     * right subtree.
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   428
                     * The left child's pending count needs to be updated before
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   429
                     * it is associated in the completion map, otherwise the
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   430
                     * left child can complete prematurely and violate the
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   431
                     * "happens-before" constraint.
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   432
                     */
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   433
                    leftChild.addToPendingCount(1);
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   434
                    // Update association of left-predecessor to left-most
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   435
                    // leaf node of right subtree
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   436
                    if (task.completionMap.replace(task.leftPredecessor, task, leftChild)) {
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   437
                        // If replaced, adjust the pending count of the parent
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   438
                        // to complete when its children complete
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   439
                        task.addToPendingCount(-1);
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   440
                    } else {
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   441
                        // Left-predecessor has already completed, parent's
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   442
                        // pending count is adjusted by left-predecessor;
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   443
                        // left child is ready to complete
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   444
                        leftChild.addToPendingCount(-1);
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   445
                    }
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   446
                }
22289
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   447
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   448
                ForEachOrderedTask<S, T> taskToFork;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   449
                if (forkRight) {
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   450
                    forkRight = false;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   451
                    rightSplit = leftSplit;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   452
                    task = leftChild;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   453
                    taskToFork = rightChild;
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   454
                }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   455
                else {
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   456
                    forkRight = true;
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   457
                    task = rightChild;
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   458
                    taskToFork = leftChild;
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   459
                }
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   460
                taskToFork.fork();
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   461
            }
22289
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   462
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   463
            /*
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   464
             * Task's pending count is either 0 or 1.  If 1 then the completion
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   465
             * map will contain a value that is task, and two calls to
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   466
             * tryComplete are required for completion, one below and one
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   467
             * triggered by the completion of task's left-predecessor in
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   468
             * onCompletion.  Therefore there is no data race within the if
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   469
             * block.
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   470
             */
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   471
            if (task.getPendingCount() > 0) {
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   472
                // Cannot complete just yet so buffer elements into a Node
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   473
                // for use when completion occurs
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   474
                Node.Builder<T> nb = task.helper.makeNodeBuilder(
22289
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   475
                        task.helper.exactOutputSizeIfKnown(rightSplit),
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   476
                        size -> (T[]) new Object[size]);
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   477
                task.node = task.helper.wrapAndCopyInto(nb, rightSplit).build();
22289
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   478
                task.spliterator = null;
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   479
            }
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 18572
diff changeset
   480
            task.tryComplete();
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   481
        }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   482
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   483
        @Override
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   484
        public void onCompletion(CountedCompleter<?> caller) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   485
            if (node != null) {
22289
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   486
                // Dump buffered elements from this leaf into the sink
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   487
                node.forEach(action);
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   488
                node = null;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   489
            }
22289
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   490
            else if (spliterator != null) {
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   491
                // Dump elements output from this leaf's pipeline into the sink
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   492
                helper.wrapAndCopyInto(action, spliterator);
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   493
                spliterator = null;
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   494
            }
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   495
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   496
            // The completion of this task *and* the dumping of elements
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   497
            // "happens-before" completion of the associated left-most leaf task
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   498
            // of right subtree (if any, which can be this task's right sibling)
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   499
            //
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   500
            ForEachOrderedTask<S, T> leftDescendant = completionMap.remove(this);
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   501
            if (leftDescendant != null)
bb9c71b84919 8029452: Fork/Join task ForEachOps.ForEachOrderedTask clarifications and minor improvements
psandoz
parents: 19218
diff changeset
   502
                leftDescendant.tryComplete();
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   503
        }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   504
    }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   505
}