jdk/src/share/classes/java/util/stream/AbstractShortCircuitTask.java
author henryjen
Mon, 08 Jul 2013 15:46:26 -0400
changeset 18825 06636235cd12
parent 18795 25d68f4a1b38
child 19218 8e7212b90b81
permissions -rw-r--r--
8020062: Nest StreamBuilder interfaces inside relevant Stream interfaces Reviewed-by: psandoz, mduigou Contributed-by: brian goetz <brian.goetz@oracle.com>
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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.Spliterator;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    28
import java.util.concurrent.atomic.AtomicReference;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    29
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    30
/**
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    31
 * Abstract class for fork-join tasks used to implement short-circuiting
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    32
 * stream ops, which can produce a result without processing all elements of the
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    33
 * stream.
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    34
 *
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    35
 * @param <P_IN> type of input elements to the pipeline
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    36
 * @param <P_OUT> type of output elements from the pipeline
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    37
 * @param <R> type of intermediate result, may be different from operation
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    38
 *        result type
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    39
 * @param <K> type of child and sibling tasks
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    40
 * @since 1.8
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    41
 */
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    42
abstract class AbstractShortCircuitTask<P_IN, P_OUT, R,
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    43
                                        K extends AbstractShortCircuitTask<P_IN, P_OUT, R, K>>
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    44
        extends AbstractTask<P_IN, P_OUT, R, K> {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    45
    /**
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    46
     * The result for this computation; this is shared among all tasks and set
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    47
     * exactly once
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
    protected final AtomicReference<R> sharedResult;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    50
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    51
    /**
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    52
     * Indicates whether this task has been canceled.  Tasks may cancel other
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    53
     * tasks in the computation under various conditions, such as in a
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    54
     * find-first operation, a task that finds a value will cancel all tasks
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    55
     * that are later in the encounter order.
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
    protected volatile boolean canceled;
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
     * Constructor for root tasks.
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    61
     *
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    62
     * @param helper the {@code PipelineHelper} describing the stream pipeline
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    63
     *               up to this operation
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    64
     * @param spliterator the {@code Spliterator} describing the source for this
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    65
     *                    pipeline
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    66
     */
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    67
    protected AbstractShortCircuitTask(PipelineHelper<P_OUT> helper,
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    68
                                       Spliterator<P_IN> spliterator) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    69
        super(helper, spliterator);
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    70
        sharedResult = new AtomicReference<>(null);
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    71
    }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    72
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
     * Constructor for non-root nodes.
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
     * @param parent parent task in the computation tree
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    77
     * @param spliterator the {@code Spliterator} for the portion of the
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    78
     *                    computation tree described by this task
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    79
     */
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    80
    protected AbstractShortCircuitTask(K parent,
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    81
                                       Spliterator<P_IN> spliterator) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    82
        super(parent, spliterator);
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    83
        sharedResult = parent.sharedResult;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    84
    }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    85
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    86
    /**
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    87
     * Returns the value indicating the computation completed with no task
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    88
     * finding a short-circuitable result.  For example, for a "find" operation,
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    89
     * this might be null or an empty {@code Optional}.
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
     * @return the result to return when no task finds a result
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    92
     */
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    93
    protected abstract R getEmptyResult();
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    94
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
    95
    /**
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
    96
     * Overrides AbstractTask version to include checks for early
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
    97
     * exits while splitting or computing.
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
    98
     */
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
    99
    @Override
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   100
    public void compute() {
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   101
        Spliterator<P_IN> rs = spliterator, ls;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   102
        long sizeEstimate = rs.estimateSize();
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   103
        long sizeThreshold = getTargetSize(sizeEstimate);
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   104
        boolean forkRight = false;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   105
        @SuppressWarnings("unchecked") K task = (K) this;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   106
        AtomicReference<R> sr = sharedResult;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   107
        R result;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   108
        while ((result = sr.get()) == null) {
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   109
            if (task.taskCanceled()) {
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   110
                result = task.getEmptyResult();
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   111
                break;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   112
            }
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   113
            if (sizeEstimate <= sizeThreshold || (ls = rs.trySplit()) == null) {
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   114
                result = task.doLeaf();
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   115
                break;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   116
            }
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   117
            K leftChild, rightChild, taskToFork;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   118
            task.leftChild  = leftChild = task.makeChild(ls);
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   119
            task.rightChild = rightChild = task.makeChild(rs);
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   120
            task.setPendingCount(1);
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   121
            if (forkRight) {
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   122
                forkRight = false;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   123
                rs = ls;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   124
                task = leftChild;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   125
                taskToFork = rightChild;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   126
            }
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   127
            else {
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   128
                forkRight = true;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   129
                task = rightChild;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   130
                taskToFork = leftChild;
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   131
            }
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   132
            taskToFork.fork();
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   133
            sizeEstimate = rs.estimateSize();
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   134
        }
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   135
        task.setLocalResult(result);
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   136
        task.tryComplete();
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   137
    }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   138
18795
25d68f4a1b38 8020040: Improve and generalize the F/J tasks to handle right or left-balanced trees
psandoz
parents: 17163
diff changeset
   139
17163
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   140
    /**
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   141
     * Declares that a globally valid result has been found.  If another task has
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   142
     * not already found the answer, the result is installed in
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   143
     * {@code sharedResult}.  The {@code compute()} method will check
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   144
     * {@code sharedResult} before proceeding with computation, so this causes
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   145
     * the computation to terminate early.
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
     * @param result the result found
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   148
     */
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   149
    protected void shortCircuit(R result) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   150
        if (result != null)
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   151
            sharedResult.compareAndSet(null, result);
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
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   154
    /**
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   155
     * Sets a local result for this task.  If this task is the root, set the
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   156
     * shared result instead (if not already set).
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   157
     *
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   158
     * @param localResult The result to set for this task
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   159
     */
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   160
    @Override
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   161
    protected void setLocalResult(R localResult) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   162
        if (isRoot()) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   163
            if (localResult != null)
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   164
                sharedResult.compareAndSet(null, localResult);
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   165
        }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   166
        else
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   167
            super.setLocalResult(localResult);
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
    /**
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   171
     * Retrieves the local result for this task
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   172
     */
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   173
    @Override
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   174
    public R getRawResult() {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   175
        return getLocalResult();
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   176
    }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   177
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   178
    /**
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   179
     * Retrieves the local result for this task.  If this task is the root,
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   180
     * retrieves the shared result instead.
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   181
     */
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   182
    @Override
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   183
    public R getLocalResult() {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   184
        if (isRoot()) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   185
            R answer = sharedResult.get();
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   186
            return (answer == null) ? getEmptyResult() : answer;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   187
        }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   188
        else
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   189
            return super.getLocalResult();
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   190
    }
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
    /**
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   193
     * Mark this task as canceled
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   194
     */
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   195
    protected void cancel() {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   196
        canceled = true;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   197
    }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   198
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   199
    /**
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   200
     * Queries whether this task is canceled.  A task is considered canceled if
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   201
     * it or any of its parents have been canceled.
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   202
     *
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   203
     * @return {@code true} if this task or any parent is canceled.
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   204
     */
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   205
    protected boolean taskCanceled() {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   206
        boolean cancel = canceled;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   207
        if (!cancel) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   208
            for (K parent = getParent(); !cancel && parent != null; parent = parent.getParent())
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   209
                cancel = parent.canceled;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   210
        }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   211
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   212
        return cancel;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   213
    }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   214
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   215
    /**
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   216
     * Cancels all tasks which succeed this one in the encounter order.  This
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   217
     * includes canceling all the current task's right sibling, as well as the
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   218
     * later right siblings of all its parents.
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   219
     */
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   220
    protected void cancelLaterNodes() {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   221
        // Go up the tree, cancel right siblings of this node and all parents
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   222
        for (K parent = getParent(), node = (K) this; parent != null;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   223
             node = parent, parent = parent.getParent()) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   224
            // If node is a left child of parent, then has a right sibling
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   225
            if (parent.leftChild == node) {
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   226
                K rightSibling = parent.rightChild;
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   227
                if (!rightSibling.canceled)
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   228
                    rightSibling.cancel();
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   229
            }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   230
        }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   231
    }
6a5e9b4f27d2 8008670: Initial java.util.stream putback -- internal API classes
mduigou
parents:
diff changeset
   232
}