changeset 7538:0b8d535e6869

Updates to LinkedList and Vector spliterators. Contributed-by: Doug Lea <dl@cs.oswego.edu>
author psandoz
date Tue, 26 Feb 2013 16:24:08 +0100
parents 74ded82f6a9b
children eadbf7bcb6f8
files src/share/classes/java/util/LinkedList.java src/share/classes/java/util/Vector.java
diffstat 2 files changed, 31 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/util/LinkedList.java	Tue Feb 26 15:21:41 2013 +0100
+++ b/src/share/classes/java/util/LinkedList.java	Tue Feb 26 16:24:08 2013 +0100
@@ -1186,7 +1186,7 @@
         public Spliterator<E> trySplit() {
             Node<E> p; int n;
             if (getEst() > (n = batch + 1) && n > 0 && 
-                n <= MAX_BATCH && (p = current) != null) {
+                n <= MAX_BATCH && (p = current) != null && p.next != null) {
                 Object[] a = new Object[batch = n];
                 int i = 0;
                 do {
--- a/src/share/classes/java/util/Vector.java	Tue Feb 26 15:21:41 2013 +0100
+++ b/src/share/classes/java/util/Vector.java	Tue Feb 26 16:24:08 2013 +0100
@@ -1310,7 +1310,7 @@
     }
 
     Spliterator<E> spliterator() { // to be made public later
-        return new VectorSpliterator<>(this, 0, -1, 0);
+        return new VectorSpliterator<>(this, null, 0, -1, 0);
     }
 
     public Stream<E> stream() {
@@ -1324,78 +1324,73 @@
     /** Similar to ArrayList Spliterator */
     static final class VectorSpliterator<E> implements Spliterator<E> {
         private final Vector<E> list;
+        private Object[] array;
         private int index; // current index, modified on advance/split
         private int fence; // -1 until used; then one past last index
         private int expectedModCount; // initialized when fence set
 
         /** Create new spliterator covering the given  range */
-        VectorSpliterator(Vector<E> list, int origin, int fence,
-                             int expectedModCount) {
+        VectorSpliterator(Vector<E> list, Object[] array, int origin, int fence,
+                          int expectedModCount) {
             this.list = list;
+            this.array = array;
             this.index = origin;
             this.fence = fence;
             this.expectedModCount = expectedModCount;
         }
 
-        private int getFence() { // initialize fence to size on first use
+        private int getFence() { // initialize on first use
             int hi;
-            Vector<E> lst;
             if ((hi = fence) < 0) {
-                if ((lst = list) == null)
-                    hi = fence = 0;
-                else {
-                    synchronized(lst) {
-                        expectedModCount = lst.modCount;
-                        hi = fence = lst.elementCount;
-                    }
+                synchronized(list) {
+                    array = list.elementData;
+                    expectedModCount = list.modCount;
+                    hi = fence = list.elementCount;
                 }
             }
             return hi;
         }
 
-        public VectorSpliterator<E> trySplit() {
+        public Spliterator<E> trySplit() {
             int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
-            return (lo >= mid) ? null : // divide range in half unless too small
-                new VectorSpliterator<E>(list, lo, index = mid,
+            return (lo >= mid) ? null :
+                new VectorSpliterator<E>(list, array, lo, index = mid,
                                          expectedModCount);
         }
 
+        @SuppressWarnings("unchecked")
         public boolean tryAdvance(Consumer<? super E> action) {
-            int hi = getFence(), i = index, lmc;
-            if (i < hi) {
+            int i, hi;
+            if ((hi = getFence()) > (i = index)) {
                 index = i + 1;
-                @SuppressWarnings("unchecked") E e = (E)list.elementData[i];
-                action.accept(e);
-                synchronized(list) { lmc = list.modCount; }
-                if (lmc != expectedModCount)
+                action.accept((E)array[i]);
+                if (list.modCount != expectedModCount)
                     throw new ConcurrentModificationException();
                 return true;
             }
             return false;
         }
 
+        @SuppressWarnings("unchecked")
         public void forEach(Consumer<? super E> action) {
-            int i, hi, mc, lmc; // hoist accesses and checks from loop
+            int i, hi; // hoist accesses and checks from loop
             Vector<E> lst; Object[] a;
             if (action == null)
                 throw new NullPointerException();
             if ((lst = list) != null) {
-                synchronized(lst) {
-                    a = lst.elementData;
-                    if ((hi = fence) < 0) {
-                        mc = lst.modCount;
-                        hi = lst.elementCount;
+                if ((hi = fence) < 0) {
+                    synchronized(lst) {
+                        expectedModCount = lst.modCount;
+                        a = array = lst.elementData;
+                        hi = fence = lst.elementCount;
                     }
-                    else
-                        mc = expectedModCount;
                 }
+                else
+                    a = array;
                 if (a != null && (i = index) >= 0 && (index = hi) <= a.length) {
-                    for (; i < hi; ++i) {
-                        @SuppressWarnings("unchecked") E e = (E) a[i];
-                        action.accept(e);
-                    }
-                    synchronized(lst) { lmc = lst.modCount; }
-                    if (lmc == mc)
+                    while (i < hi)
+                        action.accept((E) a[i++]);
+                    if (lst.modCount == expectedModCount)
                         return;
                 }
             }