--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java Tue Jul 02 15:58:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java Wed Jul 03 11:58:09 2013 +0200
@@ -42,6 +42,9 @@
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Queue;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.Consumer;
/**
* An unbounded concurrent {@linkplain Deque deque} based on linked nodes.
@@ -816,7 +819,7 @@
* Creates an array list and fills it with elements of this list.
* Used by toArray.
*
- * @return the arrayList
+ * @return the array list
*/
private ArrayList<E> toArrayList() {
ArrayList<E> list = new ArrayList<E>();
@@ -1024,11 +1027,27 @@
}
public E poll() { return pollFirst(); }
+ public E peek() { return peekFirst(); }
+
+ /**
+ * @throws NoSuchElementException {@inheritDoc}
+ */
public E remove() { return removeFirst(); }
- public E peek() { return peekFirst(); }
+
+ /**
+ * @throws NoSuchElementException {@inheritDoc}
+ */
+ public E pop() { return removeFirst(); }
+
+ /**
+ * @throws NoSuchElementException {@inheritDoc}
+ */
public E element() { return getFirst(); }
+
+ /**
+ * @throws NullPointerException {@inheritDoc}
+ */
public void push(E e) { addFirst(e); }
- public E pop() { return removeFirst(); }
/**
* Removes the first element {@code e} such that
@@ -1385,6 +1404,99 @@
Node<E> nextNode(Node<E> p) { return pred(p); }
}
+ /** A customized variant of Spliterators.IteratorSpliterator */
+ static final class CLDSpliterator<E> implements Spliterator<E> {
+ static final int MAX_BATCH = 1 << 25; // max batch array 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;
+ final ConcurrentLinkedDeque<E> q = this.queue;
+ int b = batch;
+ int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1;
+ if (!exhausted &&
+ ((p = current) != null || (p = q.first()) != null)) {
+ if (p.item == null && p == (p = p.next))
+ current = p = q.first();
+ if (p != null && p.next != null) {
+ Object[] a = new Object[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;
+ if (i > 0) {
+ batch = i;
+ return Spliterators.spliterator
+ (a, 0, i, Spliterator.ORDERED | Spliterator.NONNULL |
+ Spliterator.CONCURRENT);
+ }
+ }
+ }
+ return null;
+ }
+
+ public void forEachRemaining(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 long estimateSize() { return Long.MAX_VALUE; }
+
+ public int characteristics() {
+ return Spliterator.ORDERED | Spliterator.NONNULL |
+ Spliterator.CONCURRENT;
+ }
+ }
+
+ public Spliterator<E> spliterator() {
+ return new CLDSpliterator<E>(this);
+ }
+
/**
* Saves this deque to a stream (that is, serializes it).
*