Mercurial > hg > openjdk > lambda > jdk
changeset 7520:c08707396c40
Spliterator updates
Contributed-by: Doug Lea <dl@cs.oswego.edu>
author | psandoz |
---|---|
date | Fri, 22 Feb 2013 18:41:13 +0100 |
parents | 9df184b39d16 |
children | 8c3211b22686 |
files | src/share/classes/java/util/concurrent/ArrayBlockingQueue.java src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java src/share/classes/java/util/concurrent/PriorityBlockingQueue.java |
diffstat | 3 files changed, 142 insertions(+), 93 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/java/util/concurrent/ArrayBlockingQueue.java Fri Feb 22 12:33:55 2013 -0500 +++ b/src/share/classes/java/util/concurrent/ArrayBlockingQueue.java Fri Feb 22 18:41:13 2013 +0100 @@ -1,33 +1,4 @@ /* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * This file is available under and governed by the GNU General Public - * License version 2 only, as published by the Free Software Foundation. - * However, the following notice accompanied the original version of this - * file: - * * Written by Doug Lea with assistance from members of JCP JSR-166 * Expert Group and released to the public domain, as explained at * http://creativecommons.org/publicdomain/zero/1.0/ @@ -1399,8 +1370,8 @@ // } } - Spliterator<E> spliterator() { // cheaper to use snapshot than track array - return Collections.arraySnapshotSpliterator + Spliterator<E> spliterator() { + return Collections.iteratorBasedSpliterator (this, Spliterator.ORDERED | Spliterator.NONNULL | Spliterator.CONCURRENT); }
--- a/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java Fri Feb 22 12:33:55 2013 -0500 +++ b/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java Fri Feb 22 18:41:13 2013 +0100 @@ -1,33 +1,4 @@ /* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * This file is available under and governed by the GNU General Public - * License version 2 only, as published by the Free Software Foundation. - * However, the following notice accompanied the original version of this - * file: - * * Written by Doug Lea and Martin Buchholz with assistance from members of * JCP JSR-166 Expert Group and released to the public domain, as explained * at http://creativecommons.org/publicdomain/zero/1.0/ @@ -1390,10 +1361,86 @@ Node<E> nextNode(Node<E> p) { return pred(p); } } + // Same idea as ConcurrentLinkedQueue Spliterator + static final class CLDSpliterator<E> implements Spliterator<E> { + static final int MAX_BATCH = 1 << 10; // saturate batch size + final ConcurrentLinkedDeque<E> queue; + Node<E> current; // current node; null until initialized + int batch; // batch size for splits + boolean exhausted; // true when no more nodes + CLDSpliterator(ConcurrentLinkedDeque<E> queue) { + this.queue = queue; + } + + public Spliterator<E> trySplit() { + Node<E> p; int n; + final ConcurrentLinkedDeque<E> q = this.queue; + if (!exhausted && (n = batch + 1) > 0 && n <= MAX_BATCH && + ((p = current) != null || (p = q.first()) != null)) { + Object[] a = new Object[batch = n]; + int i = 0; + do { + if ((a[i] = p.item) != null) + ++i; + if (p == (p = p.next)) + p = q.first(); + } while (p != null && i < n); + if ((current = p) == null) + exhausted = true; + return Collections.arraySnapshotSpliterator + (a, 0, i, Spliterator.ORDERED | Spliterator.NONNULL | + Spliterator.CONCURRENT); + } + return null; + } + + public void forEach(Consumer<? super E> action) { + Node<E> p; + if (action == null) throw new NullPointerException(); + final ConcurrentLinkedDeque<E> q = this.queue; + if (!exhausted && + ((p = current) != null || (p = q.first()) != null)) { + exhausted = true; + do { + E e = p.item; + if (p == (p = p.next)) + p = q.first(); + if (e != null) + action.accept(e); + } while (p != null); + } + } + + public boolean tryAdvance(Consumer<? super E> action) { + Node<E> p; + if (action == null) throw new NullPointerException(); + final ConcurrentLinkedDeque<E> q = this.queue; + if (!exhausted && + ((p = current) != null || (p = q.first()) != null)) { + E e; + do { + e = p.item; + if (p == (p = p.next)) + p = q.first(); + } while (e == null && p != null); + if ((current = p) == null) + exhausted = true; + if (e != null) { + action.accept(e); + return true; + } + } + return false; + } + + public int characteristics() { + return Spliterator.ORDERED | Spliterator.NONNULL | + Spliterator.CONCURRENT; + } + } + Spliterator<E> spliterator() { - return Collections.iteratorBasedSpliterator - (iterator(), Spliterator.ORDERED | Spliterator.NONNULL | - Spliterator.CONCURRENT); + return new CLDSpliterator<E>(this); } public Stream<E> stream() {
--- a/src/share/classes/java/util/concurrent/PriorityBlockingQueue.java Fri Feb 22 12:33:55 2013 -0500 +++ b/src/share/classes/java/util/concurrent/PriorityBlockingQueue.java Fri Feb 22 18:41:13 2013 +0100 @@ -1,33 +1,4 @@ /* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * This file is available under and governed by the GNU General Public - * License version 2 only, as published by the Free Software Foundation. - * However, the following notice accompanied the original version of this - * file: - * * Written by Doug Lea with assistance from members of JCP JSR-166 * Expert Group and released to the public domain, as explained at * http://creativecommons.org/publicdomain/zero/1.0/ @@ -948,8 +919,68 @@ } } + // Similar to Collections.ArraySnapshotSpliterator but avoids + // commitment to toArray until needed + static final class PBQSpliterator<E> implements Spliterator<E> { + final PriorityBlockingQueue<E> queue; + Object[] array; + int index; + int fence; + + PBQSpliterator(PriorityBlockingQueue<E> queue, Object[] array, + int index, int fence) { + this.queue = queue; + this.array = array; + this.index = index; + this.fence = fence; + } + + final int getFence() { + int hi; + if ((hi = fence) < 0) + hi = fence = (array = queue.toArray()).length; + return hi; + } + + public Spliterator<E> trySplit() { + int hi = getFence(), lo = index, mid = (lo + hi) >>> 1; + return (lo >= mid) ? null : + new PBQSpliterator<E>(queue, array, lo, index = mid); + } + + @SuppressWarnings("unchecked") + public void forEach(Consumer<? super E> action) { + Object[] a; int i, hi; // hoist accesses and checks from loop + if (action == null) + throw new NullPointerException(); + if ((a = array) == null) + fence = (a = queue.toArray()).length; + if ((hi = fence) <= a.length && + (i = index) >= 0 && i < (index = hi)) { + do { action.accept((E)a[i]); } while (++i < hi); + } + } + + public boolean tryAdvance(Consumer<? super E> action) { + if (action == null) + throw new NullPointerException(); + if (getFence() > index && index >= 0) { + @SuppressWarnings("unchecked") E e = (E) array[index++]; + action.accept(e); + return true; + } + return false; + } + + public long estimateSize() { return (long)(getFence() - index); } + + public int characteristics() { + return Spliterator.NONNULL | Spliterator.SIZED | Spliterator.SUBSIZED; + } + } + Spliterator<E> spliterator() { - return Collections.arraySnapshotSpliterator(this, 0); + return new PBQSpliterator<E>(this, null, 0, -1); } public Stream<E> stream() { return Streams.stream(spliterator());