changeset 6815:7266dd644226

Change accessor for Node children from an iterator to a get with index.
author psandoz
date Fri, 14 Dec 2012 20:42:01 +0100
parents cc5c324cb654
children 5d25f6772fec
files src/share/classes/java/util/stream/op/Node.java src/share/classes/java/util/stream/op/NodeUtils.java src/share/classes/java/util/stream/op/Nodes.java src/share/classes/java/util/stream/primitive/IntNodeUtils.java src/share/classes/java/util/stream/primitive/PrimitiveNode.java src/share/classes/java/util/stream/primitive/PrimitiveNodes.java
diffstat 6 files changed, 104 insertions(+), 140 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/util/stream/op/Node.java	Fri Dec 14 17:14:19 2012 +0100
+++ b/src/share/classes/java/util/stream/op/Node.java	Fri Dec 14 20:42:01 2012 +0100
@@ -44,11 +44,15 @@
     }
 
     /**
+     * Get a child node at a given index.
      *
-     * @return the child nodes.
+     * @param i the index to the child node
+     * @return the child node.
+     * @throws IndexOutOfBoundsException if the index is less than 0 or greater than or equal to the
+     * number of child nodes.
      */
-    default Iterator<? extends Node<T>> children() {
-        return Collections.emptyIterator();
+    default Node<T> getChild(int i) {
+        throw new IndexOutOfBoundsException();
     }
 
     /**
--- a/src/share/classes/java/util/stream/op/NodeUtils.java	Fri Dec 14 17:14:19 2012 +0100
+++ b/src/share/classes/java/util/stream/op/NodeUtils.java	Fri Dec 14 20:42:01 2012 +0100
@@ -210,13 +210,11 @@
             if (node.getChildCount() > 0) {
                 setPendingCount(node.getChildCount() - 1);
 
-                final Iterator<? extends Node<T>> itNodes = node.children();
-
-                final ToArrayTask<T> firstTask = new ToArrayTask<>(this, itNodes.next(), offset);
+                final ToArrayTask<T> firstTask = new ToArrayTask<>(this, node.getChild(0), offset);
                 int size = (int) firstTask.node.count();
 
-                while (itNodes.hasNext()) {
-                    final ToArrayTask<T> task = new ToArrayTask<>(this, itNodes.next(), offset + size);
+                for (int i = 1; i < node.getChildCount(); i++) {
+                    final ToArrayTask<T> task = new ToArrayTask<>(this, node.getChild(i), offset + size);
                     size += task.node.count();
                     task.fork();
                 }
--- a/src/share/classes/java/util/stream/op/Nodes.java	Fri Dec 14 17:14:19 2012 +0100
+++ b/src/share/classes/java/util/stream/op/Nodes.java	Fri Dec 14 20:42:01 2012 +0100
@@ -28,6 +28,7 @@
 import java.util.function.Block;
 import java.util.function.UnaryOperator;
 import java.util.stream.*;
+import java.util.stream.primitive.PrimitiveNode;
 
 public final class Nodes {
 
@@ -334,26 +335,8 @@
         }
 
         @Override
-        public Iterator<Node<T>> children() {
-            // @@@ This is more effiecient than Arrays.iterator(nodes)
-            //     which should be updated to not create an iteratable then an iterator
-            return new Iterator<Node<T>>() {
-                int i = 0;
-
-                @Override
-                public boolean hasNext() {
-                    return i < nodes.length;
-                }
-
-                @Override
-                public Node<T> next() {
-                    try {
-                        return nodes[i++];
-                    } catch (IndexOutOfBoundsException e) {
-                        throw new NoSuchElementException();
-                    }
-                }
-            };
+        public Node<T> getChild(int i) {
+            return nodes[i];
         }
 
         @Override
@@ -420,32 +403,49 @@
 
         private static class ConcNodeSpliterator<T> implements Spliterator<T> {
             private Node<T> cur;
-            private Iterator<? extends Node<T>> children;
             private int splitsLeft;
             private Iterator<T> iterator;
 
             private ConcNodeSpliterator(ConcNode<T> cur) {
                 this.cur = cur;
-                this.children = cur.children();
                 this.splitsLeft = cur.getChildCount() - 1;
             }
 
+            private int currentChildOffset() {
+                return cur.getChildCount() - 1 - splitsLeft;
+            }
+
+            private Node<T> currentChild() {
+                return cur.getChild(currentChildOffset());
+            }
+
+            private boolean isUnsplitOrNoMoreSplits() {
+                return splitsLeft == 0 || splitsLeft == cur.getChildCount() - 1;
+            }
+
             public Iterator<T> iterator() {
                 if (iterator == null) {
-                    if (splitsLeft == 0 || splitsLeft == cur.getChildCount() - 1) {
+                    if (isUnsplitOrNoMoreSplits()) {
                         iterator = cur.iterator();
                     } else {
-                        Iterator<? extends Node<T>> c = cur.children();
-                        int skip = cur.getChildCount() - 1 - splitsLeft;
-                        while (skip-- > 0) {
-                            c.next();
-                        }
+                        iterator = Iterators.concat(new Iterator<Iterator<T>>() {
+                            final Node<T> n = cur;
+                            int o = currentChildOffset();
 
-                        List<Iterator<T>> l = new ArrayList<>();
-                        while (c.hasNext()) {
-                            l.add(c.next().iterator());
-                        }
-                        Iterators.concat(l.iterator());
+                            @Override
+                            public boolean hasNext() {
+                                return o < n.getChildCount();
+                            }
+
+                            @Override
+                            public Iterator<T> next() {
+                                if (!hasNext()) {
+                                    throw new NoSuchElementException();
+                                }
+
+                                return n.getChild(o++).iterator();
+                            }
+                        });
                     }
                 }
                 return iterator;
@@ -453,7 +453,7 @@
 
             @Override
             public int getNaturalSplits() {
-                return splitsLeft;
+                return (iterator == null) ? splitsLeft : 0;
             }
 
             @Override
@@ -463,17 +463,10 @@
                 else if (splitsLeft == 0)
                     return Streams.emptySpliterator();
                 else {
-                    Spliterator<T> ret = children.next().spliterator();
+                    Spliterator<T> ret = currentChild().spliterator();
                     if (--splitsLeft == 0) {
-                        cur = children.next();
-                        if (cur.getChildCount() > 0) {
-                            children = cur.children();
-                            splitsLeft = cur.getChildCount() - 1;
-                        }
-                        else {
-                            children = Collections.emptyIterator();
-                            splitsLeft = 0;
-                        }
+                        cur = currentChild();
+                        splitsLeft = (cur.getChildCount() > 0) ? splitsLeft = cur.getChildCount() - 1 : 0;
                     }
                     return ret;
                 }
@@ -482,12 +475,12 @@
             @Override
             public void forEach(Block<? super T> block) {
                 if (iterator == null) {
-                    if (splitsLeft == 0 || splitsLeft == cur.getChildCount() - 1) {
+                    if (isUnsplitOrNoMoreSplits()) {
                         cur.forEach(block);
                     }
                     else {
-                        while (children.hasNext()) {
-                            children.next().forEach(block);
+                        for (int i = currentChildOffset(); i < cur.getChildCount(); i++) {
+                            cur.getChild(i).forEach(block);
                         }
                     }
                     iterator = Collections.emptyIterator();
@@ -500,19 +493,13 @@
             @Override
             public long getSizeIfKnown() {
                 if (iterator == null) {
-                    if (splitsLeft == 0 || splitsLeft == cur.getChildCount() - 1) {
+                    if (isUnsplitOrNoMoreSplits()) {
                         return cur.count();
                     }
                     else {
-                        Iterator<? extends Node<T>> c = cur.children();
-                        int skip = cur.getChildCount() - 1 - splitsLeft;
-                        while (skip-- > 0) {
-                            c.next();
-                        }
-
                         long size = 0;
-                        while (c.hasNext()) {
-                            size += c.next().count();
+                        for (int i = currentChildOffset(); i < cur.getChildCount(); i++) {
+                            size += cur.getChild(i).count();
                         }
                         return size;
                     }
--- a/src/share/classes/java/util/stream/primitive/IntNodeUtils.java	Fri Dec 14 17:14:19 2012 +0100
+++ b/src/share/classes/java/util/stream/primitive/IntNodeUtils.java	Fri Dec 14 20:42:01 2012 +0100
@@ -217,15 +217,11 @@
             if (node.getChildCount() > 0) {
                 setPendingCount(node.getChildCount() - 1);
 
-                final Iterator<? extends PrimitiveNode<Integer>> itNodes = node.children();
-
-                // @@@ cast
-                final IntToArrayTask firstTask = new IntToArrayTask(this, itNodes.next(), offset);
+                final IntToArrayTask firstTask = new IntToArrayTask(this, node.getChild(0), offset);
                 int size = (int) firstTask.node.count();
 
-                while (itNodes.hasNext()) {
-                    // @@@ cast
-                    final IntToArrayTask task = new IntToArrayTask(this, itNodes.next(), offset + size);
+                for (int i = 1; i < node.getChildCount(); i++) {
+                    final IntToArrayTask task = new IntToArrayTask(this, node.getChild(i), offset + size);
                     size += task.node.count();
                     task.fork();
                 }
--- a/src/share/classes/java/util/stream/primitive/PrimitiveNode.java	Fri Dec 14 17:14:19 2012 +0100
+++ b/src/share/classes/java/util/stream/primitive/PrimitiveNode.java	Fri Dec 14 20:42:01 2012 +0100
@@ -31,8 +31,8 @@
 public interface PrimitiveNode<E> extends Node<E>, PrimitiveIterable<E> {
 
     @Override
-    default Iterator<? extends PrimitiveNode<E>> children() {
-        return Collections.emptyIterator();
+    default PrimitiveNode<E> getChild(int i) {
+        throw new IndexOutOfBoundsException();
     }
 
     @Override
@@ -61,11 +61,6 @@
 
     interface OfInt extends PrimitiveNode<Integer>, PrimitiveIterable.OfInt {
 
-//        @Override
-//        default Iterator<PrimitiveNode.OfInt> children() {
-//            return Collections.emptyIterator();
-//        }
-
         int[] asIntArray();
 
         void copyInto(int[] array, int offset) throws IndexOutOfBoundsException;
--- a/src/share/classes/java/util/stream/primitive/PrimitiveNodes.java	Fri Dec 14 17:14:19 2012 +0100
+++ b/src/share/classes/java/util/stream/primitive/PrimitiveNodes.java	Fri Dec 14 20:42:01 2012 +0100
@@ -27,6 +27,7 @@
 import java.util.*;
 import java.util.function.Block;
 import java.util.function.IntBlock;
+import java.util.stream.op.Node;
 
 public final class PrimitiveNodes {
 
@@ -102,25 +103,8 @@
         }
 
         @Override
-        public Iterator<? extends PrimitiveNode<E>> children() {
-            return new Iterator<PrimitiveNode<E>>() {
-                int i = 0;
-
-                @Override
-                public boolean hasNext() {
-                    return i < nodes.length;
-                }
-
-                @Override
-                public PrimitiveNode<E> next() {
-                    try {
-                        return nodes[i++];
-                    }
-                    catch (IndexOutOfBoundsException e) {
-                        throw new NoSuchElementException();
-                    }
-                }
-            };
+        public PrimitiveNode<E> getChild(int i) {
+            return nodes[i];
         }
 
         @Override
@@ -183,33 +167,50 @@
 
         private static class PrimitiveConcNodeSpliterator<E> implements PrimitiveSpliterator<E> {
             private PrimitiveNode<E> cur;
-            private Iterator<? extends PrimitiveNode<E>> children;
             private int splitsLeft;
             private PrimitiveIterator<E> iterator;
 
             private PrimitiveConcNodeSpliterator(PrimitiveNode<E> cur) {
                 this.cur = cur;
-                this.children = cur.children();
                 this.splitsLeft = cur.getChildCount() - 1;
             }
 
+            private int currentChildOffset() {
+                return cur.getChildCount() - 1 - splitsLeft;
+            }
+
+            private PrimitiveNode<E> currentChild() {
+                return cur.getChild(currentChildOffset());
+            }
+
+            private boolean isUnsplitOrNoMoreSplits() {
+                return splitsLeft == 0 || splitsLeft == cur.getChildCount() - 1;
+            }
+
             public PrimitiveIterator<E> iterator() {
                 if (iterator == null) {
-                    if (splitsLeft == 0 || splitsLeft == cur.getChildCount() - 1) {
+                    if (isUnsplitOrNoMoreSplits()) {
                         iterator = cur.iterator();
                     }
                     else {
-                        Iterator<? extends PrimitiveNode<E>> c = cur.children();
-                        int skip = cur.getChildCount() - 1 - splitsLeft;
-                        while (skip-- > 0) {
-                            c.next();
-                        }
+                        iterator = PrimitiveStreams.concat(new Iterator<PrimitiveIterator<E>>() {
+                            final PrimitiveNode<E> n = cur;
+                            int o = currentChildOffset();
 
-                        List<PrimitiveIterator<E>> l = new ArrayList<>();
-                        while (c.hasNext()) {
-                            l.add(c.next().iterator());
-                        }
-                        PrimitiveStreams.concat(l.iterator());
+                            @Override
+                            public boolean hasNext() {
+                                return o < n.getChildCount();
+                            }
+
+                            @Override
+                            public PrimitiveIterator<E> next() {
+                                if (!hasNext()) {
+                                    throw new NoSuchElementException();
+                                }
+
+                                return n.getChild(o++).iterator();
+                            }
+                        });
                     }
                 }
                 return iterator;
@@ -217,7 +218,7 @@
 
             @Override
             public int getNaturalSplits() {
-                return splitsLeft;
+                return (iterator == null) ? splitsLeft : 0;
             }
 
             @Override
@@ -227,26 +228,15 @@
                 else if (splitsLeft == 0)
                     return PrimitiveStreams.emptyPrimitiveSpliterator();
                 else {
-                    PrimitiveSpliterator<E> ret = nextChild().spliterator();
+                    PrimitiveSpliterator<E> ret = currentChild().spliterator();
                     if (--splitsLeft == 0) {
-                        cur = nextChild();
-                        if (cur.getChildCount() > 0) {
-                            children = cur.children();
-                            splitsLeft = cur.getChildCount() - 1;
-                        }
-                        else {
-                            children = Collections.emptyIterator();
-                            splitsLeft = 0;
-                        }
+                        cur = currentChild();
+                        splitsLeft = (cur.getChildCount() > 0) ? splitsLeft = cur.getChildCount() - 1 : 0;
                     }
                     return ret;
                 }
             }
 
-            private PrimitiveNode<E> nextChild() {
-                return children.next();
-            }
-
             @Override
             public void forEach(Block<? super E> block) {
                 if (block instanceof IntBlock) {
@@ -254,12 +244,12 @@
                 }
                 else {
                     if (iterator == null) {
-                        if (splitsLeft == 0 || splitsLeft == cur.getChildCount() - 1) {
+                        if (isUnsplitOrNoMoreSplits()) {
                             cur.forEach(block);
                         }
                         else {
-                            while (children.hasNext()) {
-                                children.next().forEach(block);
+                            for (int i = currentChildOffset(); i < cur.getChildCount(); i++) {
+                                cur.getChild(i).forEach(block);
                             }
                         }
                         iterator = PrimitiveStreams.emptyPrimitiveIterator();
@@ -273,12 +263,12 @@
             @Override
             public void forEach(IntBlock block) {
                 if (iterator == null) {
-                    if (splitsLeft == 0 || splitsLeft == cur.getChildCount() - 1) {
+                    if (isUnsplitOrNoMoreSplits()) {
                         cur.forEach(block);
                     }
                     else {
-                        while (children.hasNext()) {
-                            children.next().forEach(block);
+                        for (int i = currentChildOffset(); i < cur.getChildCount(); i++) {
+                            cur.getChild(i).forEach(block);
                         }
                     }
                     iterator = PrimitiveStreams.emptyPrimitiveIterator();
@@ -291,19 +281,13 @@
             @Override
             public long getSizeIfKnown() {
                 if (iterator == null) {
-                    if (splitsLeft == 0 || splitsLeft == cur.getChildCount() - 1) {
+                    if (isUnsplitOrNoMoreSplits()) {
                         return cur.count();
                     }
                     else {
-                        Iterator<? extends PrimitiveNode<E>> c = cur.children();
-                        int skip = cur.getChildCount() - 1 - splitsLeft;
-                        while (skip-- > 0) {
-                            c.next();
-                        }
-
                         long size = 0;
-                        while (c.hasNext()) {
-                            size += c.next().count();
+                        for (int i = currentChildOffset(); i < cur.getChildCount(); i++) {
+                            size += cur.getChild(i).count();
                         }
                         return size;
                     }