changeset 6637:cb93b3229345

More spliterator tests and fixes
author briangoetz
date Tue, 27 Nov 2012 18:07:29 -0500
parents 956b0f5d580b
children 44fd54f2a41d
files src/share/classes/java/util/stream/op/SpinedList.java test-ng/tests/org/openjdk/tests/java/util/stream/SpliteratorTest.java
diffstat 2 files changed, 35 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/util/stream/op/SpinedList.java	Tue Nov 27 16:30:06 2012 -0500
+++ b/src/share/classes/java/util/stream/op/SpinedList.java	Tue Nov 27 18:07:29 2012 -0500
@@ -344,22 +344,17 @@
 
     class SpinedListSpliterator implements Spliterator<E>, Iterator<E> {
         Iterator<E> iterator = null;
-
         boolean traversing = false;
-
-        boolean isSpinedSpliterator = true;
-
+        boolean notLastChunk = true;
         int spineOffset = 0;
-
         E[] elements;
-
         int offset;
-
         int endOffset;
+        int totalDispensedSize;
 
         SpinedListSpliterator() {
             if (spineOffset == spineIndex) {
-                isSpinedSpliterator = false;
+                notLastChunk = false;
                 elements = chunk;
                 offset = 0;
                 endOffset = chunkIndex;
@@ -368,41 +363,25 @@
 
         @Override
         public int getSizeIfKnown() {
-            if (isSpinedSpliterator) {
-                // @@@ This will not return the correct known size if iterated on
-                int result = SpinedList.this.size();
-                if (spineOffset > 0) {
-                    result -= SpinedList.totalSizeForSpineIndex(spineOffset - 1);
-                }
-
-                return result;
-            }
-            else {
-                return endOffset - offset;
-            }
+            return notLastChunk
+                   ? SpinedList.this.size() - totalDispensedSize
+                   : endOffset - offset;
         }
 
         @Override
         public Iterator<E> iterator() {
             traversing = true;
-
-            if (iterator != null) {
-                return iterator;
+            if (iterator == null) {
+                iterator = notLastChunk ? SpinedList.this.iterator(spineOffset) : this;
             }
-
-            if (isSpinedSpliterator) {
-                return iterator = SpinedList.this.iterator(spineOffset);
-            }
-            else {
-                return iterator = this;
-            }
+            return iterator;
         }
 
         @Override
         public void forEach(Block<? super E> block) {
             traversing = true;
 
-            if (isSpinedSpliterator) {
+            if (notLastChunk) {
                 iterator().forEach(block);
             }
             else {
@@ -438,12 +417,10 @@
             if (traversing) {
                 return 0;
             }
-
-            if (isSpinedSpliterator) {
-                return spineIndex - spineOffset + (chunkIndex > 1 ? 1 : 0);
-            }
             else {
-                return (endOffset - offset > 1) ? 1 : 0;
+                return notLastChunk
+                                       ? spineIndex - spineOffset + (chunkIndex > 1 ? 1 : 0)
+                                       : (endOffset - offset > 1) ? 1 : 0;
             }
         }
 
@@ -453,11 +430,12 @@
                 throw new IllegalStateException("split after starting traversal");
             }
 
-            if (isSpinedSpliterator) {
+            if (notLastChunk) {
+                totalDispensedSize += spine[spineOffset].length;
                 Spliterator<E> ret = Arrays.spliterator(spine[spineOffset++]);
 
                 if (spineOffset == spineIndex) {
-                    isSpinedSpliterator = false;
+                    notLastChunk = false;
                     elements = chunk;
                     offset = 0;
                     endOffset = chunkIndex;
--- a/test-ng/tests/org/openjdk/tests/java/util/stream/SpliteratorTest.java	Tue Nov 27 16:30:06 2012 -0500
+++ b/test-ng/tests/org/openjdk/tests/java/util/stream/SpliteratorTest.java	Tue Nov 27 18:07:29 2012 -0500
@@ -33,9 +33,7 @@
 import java.util.function.Supplier;
 import java.util.stream.Spliterator;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.fail;
+import static org.testng.Assert.*;
 
 /**
  * SpliteratorTest
@@ -73,17 +71,16 @@
 
         ArrayList<Integer> fromSplit = new ArrayList<>();
         Spliterator<Integer> s1 = supplier.get();
+        Spliterator<Integer> s2 = s1.split();
         int s1Size = s1.getSizeIfKnown();
-        Spliterator<Integer> s2 = s1.split();
         int s2Size = s2.getSizeIfKnown();
         s2.forEach(e -> fromSplit.add(e));
         s1.forEach(e -> fromSplit.add(e));
 
         if (sizeIfKnown >= 0) {
             assertEquals(sizeIfKnown, fromSplit.size());
-            // @@@ The following finds errors, fix them!
-//            if (s1Size >= 0 && s2Size >= 0)
-//                assertEquals(sizeIfKnown, s1Size + s2Size);
+            if (s1Size >= 0 && s2Size >= 0)
+                assertEquals(sizeIfKnown, s1Size + s2Size);
         }
         assertEquals(fromSplit, fromIterator);
     }
@@ -126,24 +123,34 @@
             ArrayList<Integer> dest = new ArrayList<>();
             Spliterator<Integer> spliterator = supplier.get();
             // verify splitting with forEach
-            visit(depth, 0, dest, spliterator, false);
+            visit(depth, 0, dest, spliterator, spliterator.isPredictableSplits(), false);
             assertEquals(fromIterator, dest);
 
             // verify splitting with iterator
             dest.clear();
             spliterator = supplier.get();
-            visit(depth, 0, dest, spliterator, true);
+            visit(depth, 0, dest, spliterator, spliterator.isPredictableSplits(), true);
             assertEquals(fromIterator, dest);
         }
     }
 
-    private void visit(int depth, int curLevel, List<Integer> dest, Spliterator<Integer> spliterator, boolean useIterator) {
+    private void visit(int depth, int curLevel, List<Integer> dest, Spliterator<Integer> spliterator, boolean isPredictable, boolean useIterator) {
         if (curLevel < depth) {
             int splits = spliterator.getNaturalSplits();
             for (int i=0; i<splits; i++) {
-                visit(depth, curLevel + 1, dest, spliterator.split(), useIterator);
+                int beforeSize = spliterator.getSizeIfKnown();
+                Spliterator<Integer> split = spliterator.split();
+                if (isPredictable) {
+                    int leftSize = split.getSizeIfKnown();
+                    int rightSize = spliterator.getSizeIfKnown();
+                    assertTrue(beforeSize >= 0);
+                    assertTrue(leftSize >= 0);
+                    assertTrue(rightSize >= 0);
+                    assertEquals(beforeSize, leftSize+rightSize);
+                }
+                visit(depth, curLevel + 1, dest, split, isPredictable, useIterator);
             }
-            visit(depth, curLevel + 1, dest, spliterator, useIterator);
+            visit(depth, curLevel + 1, dest, spliterator, isPredictable, useIterator);
         }
         else {
             int sizeIfKnown = spliterator.getSizeIfKnown();