changeset 6381:9de13de7fc77

Convert AbstractTask to compute down the left spine instead of right spine; this avoids a data race from previous version and offers better behavior for findFirst/limit/skip.
author briangoetz
date Thu, 08 Nov 2012 19:09:44 -0500
parents b734873a4c79
children 887edbc2572b
files src/share/classes/java/util/streams/ops/AbstractTask.java
diffstat 1 files changed, 29 insertions(+), 58 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/util/streams/ops/AbstractTask.java	Wed Nov 07 13:24:34 2012 +0100
+++ b/src/share/classes/java/util/streams/ops/AbstractTask.java	Thu Nov 08 19:09:44 2012 -0500
@@ -92,67 +92,38 @@
         }
         else {
             int naturalSplits = spliterator.getNaturalSplits();
-            T curChild = null;
-            setPendingCount(naturalSplits);
-            numChildren = naturalSplits + 1;
-            for (int i=0; i<naturalSplits; i++) {
-                T newChild = makeChild(spliterator.split());
-                if (curChild == null)
-                    children = newChild;
-                else
+            if (naturalSplits == 0) {
+                // Shouldn't get here, but if we do, act like a leaf
+                setRawResult(doLeaf());
+                helpComplete();
+            }
+            else if (naturalSplits == 1) {
+                // Common case -- binary splits
+                T leftChild = makeChild(spliterator.split());
+                T rightChild = makeChild(spliterator);
+                setPendingCount(1);
+                numChildren = 2;
+                children = leftChild;
+                leftChild.nextSibling = rightChild;
+                rightChild.fork();
+                leftChild.compute();
+            }
+            else {
+                T firstChild = makeChild(spliterator.split());
+                setPendingCount(naturalSplits);
+                numChildren = naturalSplits + 1;
+                children = firstChild;
+                T curChild = firstChild;
+                for (int i=naturalSplits-1; i >= 0; i--) {
+                    T newChild = makeChild((i > 0) ? spliterator.split() : spliterator);
                     curChild.nextSibling = newChild;
-                curChild = newChild;
-                newChild.fork();
+                    curChild = newChild;
+                    newChild.fork();
+                }
+
+                firstChild.compute();
             }
-
-            T lastChild = makeChild(spliterator);
-            curChild.nextSibling = lastChild;
-            lastChild.compute();
         }
     }
 }
 
-abstract class ComparableTask<P_IN, P_OUT, R, T extends ComparableTask<P_IN, P_OUT, R, T>>
-        extends AbstractTask<P_IN, P_OUT, R, T>
-        implements Comparable<T> {
-    protected final int depth;
-
-    protected ComparableTask(ParallelPipelineHelper<P_IN, P_OUT> helper) {
-        super(helper);
-        depth = 0;
-    }
-
-    protected ComparableTask(T parent, Spliterator<P_IN> spliterator) {
-        super(parent, spliterator);
-        depth = parent.depth + 1;
-    }
-
-    @Override
-    public int compareTo(T o) {
-        if (this == o)
-            return 0;
-        ComparableTask<P_IN, P_OUT, R, T> me = this;
-        T other = o;
-        if (me.depth < other.depth) {
-            while (me.depth < other.depth)
-                other = other.getParent();
-        }
-        else if (other.depth < me.depth) {
-            while (other.depth < me.depth)
-                me = (T) me.getParent();
-        }
-        while (me.getCompleter() != other.getCompleter()) {
-            me = me.getParent();
-            other = other.getParent();
-        }
-        ComparableTask<P_IN, P_OUT, R, T> child = me.getParent().children;
-        for (; child != null; child = child.nextSibling) {
-            if (child == me)
-                return -1;
-            else if (child == other)
-                return 1;
-        }
-        throw new IllegalStateException();
-    }
-}
-