rt/emul/compact/src/main/java/java/util/concurrent/ConcurrentLinkedDeque.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Sat, 19 Mar 2016 12:51:03 +0100
changeset 1895 bfaf3300b7ba
parent 1890 212417b74b72
permissions -rw-r--r--
Making java.util.concurrent package compilable except ForkJoinPool
jaroslav@1890
     1
/*
jaroslav@1890
     2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jaroslav@1890
     3
 *
jaroslav@1890
     4
 * This code is free software; you can redistribute it and/or modify it
jaroslav@1890
     5
 * under the terms of the GNU General Public License version 2 only, as
jaroslav@1890
     6
 * published by the Free Software Foundation.  Oracle designates this
jaroslav@1890
     7
 * particular file as subject to the "Classpath" exception as provided
jaroslav@1890
     8
 * by Oracle in the LICENSE file that accompanied this code.
jaroslav@1890
     9
 *
jaroslav@1890
    10
 * This code is distributed in the hope that it will be useful, but WITHOUT
jaroslav@1890
    11
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jaroslav@1890
    12
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
jaroslav@1890
    13
 * version 2 for more details (a copy is included in the LICENSE file that
jaroslav@1890
    14
 * accompanied this code).
jaroslav@1890
    15
 *
jaroslav@1890
    16
 * You should have received a copy of the GNU General Public License version
jaroslav@1890
    17
 * 2 along with this work; if not, write to the Free Software Foundation,
jaroslav@1890
    18
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jaroslav@1890
    19
 *
jaroslav@1890
    20
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
jaroslav@1890
    21
 * or visit www.oracle.com if you need additional information or have any
jaroslav@1890
    22
 * questions.
jaroslav@1890
    23
 */
jaroslav@1890
    24
jaroslav@1890
    25
/*
jaroslav@1890
    26
 * This file is available under and governed by the GNU General Public
jaroslav@1890
    27
 * License version 2 only, as published by the Free Software Foundation.
jaroslav@1890
    28
 * However, the following notice accompanied the original version of this
jaroslav@1890
    29
 * file:
jaroslav@1890
    30
 *
jaroslav@1890
    31
 * Written by Doug Lea and Martin Buchholz with assistance from members of
jaroslav@1890
    32
 * JCP JSR-166 Expert Group and released to the public domain, as explained
jaroslav@1890
    33
 * at http://creativecommons.org/publicdomain/zero/1.0/
jaroslav@1890
    34
 */
jaroslav@1890
    35
jaroslav@1890
    36
package java.util.concurrent;
jaroslav@1890
    37
jaroslav@1890
    38
import java.util.AbstractCollection;
jaroslav@1890
    39
import java.util.ArrayList;
jaroslav@1890
    40
import java.util.Collection;
jaroslav@1890
    41
import java.util.Deque;
jaroslav@1890
    42
import java.util.Iterator;
jaroslav@1890
    43
import java.util.NoSuchElementException;
jaroslav@1890
    44
import java.util.Queue;
jaroslav@1890
    45
jaroslav@1890
    46
/**
jaroslav@1890
    47
 * An unbounded concurrent {@linkplain Deque deque} based on linked nodes.
jaroslav@1890
    48
 * Concurrent insertion, removal, and access operations execute safely
jaroslav@1890
    49
 * across multiple threads.
jaroslav@1890
    50
 * A {@code ConcurrentLinkedDeque} is an appropriate choice when
jaroslav@1890
    51
 * many threads will share access to a common collection.
jaroslav@1890
    52
 * Like most other concurrent collection implementations, this class
jaroslav@1890
    53
 * does not permit the use of {@code null} elements.
jaroslav@1890
    54
 *
jaroslav@1890
    55
 * <p>Iterators are <i>weakly consistent</i>, returning elements
jaroslav@1890
    56
 * reflecting the state of the deque at some point at or since the
jaroslav@1890
    57
 * creation of the iterator.  They do <em>not</em> throw {@link
jaroslav@1890
    58
 * java.util.ConcurrentModificationException
jaroslav@1890
    59
 * ConcurrentModificationException}, and may proceed concurrently with
jaroslav@1890
    60
 * other operations.
jaroslav@1890
    61
 *
jaroslav@1890
    62
 * <p>Beware that, unlike in most collections, the {@code size} method
jaroslav@1890
    63
 * is <em>NOT</em> a constant-time operation. Because of the
jaroslav@1890
    64
 * asynchronous nature of these deques, determining the current number
jaroslav@1890
    65
 * of elements requires a traversal of the elements, and so may report
jaroslav@1890
    66
 * inaccurate results if this collection is modified during traversal.
jaroslav@1890
    67
 * Additionally, the bulk operations {@code addAll},
jaroslav@1890
    68
 * {@code removeAll}, {@code retainAll}, {@code containsAll},
jaroslav@1890
    69
 * {@code equals}, and {@code toArray} are <em>not</em> guaranteed
jaroslav@1890
    70
 * to be performed atomically. For example, an iterator operating
jaroslav@1890
    71
 * concurrently with an {@code addAll} operation might view only some
jaroslav@1890
    72
 * of the added elements.
jaroslav@1890
    73
 *
jaroslav@1890
    74
 * <p>This class and its iterator implement all of the <em>optional</em>
jaroslav@1890
    75
 * methods of the {@link Deque} and {@link Iterator} interfaces.
jaroslav@1890
    76
 *
jaroslav@1890
    77
 * <p>Memory consistency effects: As with other concurrent collections,
jaroslav@1890
    78
 * actions in a thread prior to placing an object into a
jaroslav@1890
    79
 * {@code ConcurrentLinkedDeque}
jaroslav@1890
    80
 * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
jaroslav@1890
    81
 * actions subsequent to the access or removal of that element from
jaroslav@1890
    82
 * the {@code ConcurrentLinkedDeque} in another thread.
jaroslav@1890
    83
 *
jaroslav@1890
    84
 * <p>This class is a member of the
jaroslav@1890
    85
 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
jaroslav@1890
    86
 * Java Collections Framework</a>.
jaroslav@1890
    87
 *
jaroslav@1890
    88
 * @since 1.7
jaroslav@1890
    89
 * @author Doug Lea
jaroslav@1890
    90
 * @author Martin Buchholz
jaroslav@1890
    91
 * @param <E> the type of elements held in this collection
jaroslav@1890
    92
 */
jaroslav@1890
    93
jaroslav@1890
    94
public class ConcurrentLinkedDeque<E>
jaroslav@1890
    95
    extends AbstractCollection<E>
jaroslav@1890
    96
    implements Deque<E>, java.io.Serializable {
jaroslav@1890
    97
jaroslav@1890
    98
    /*
jaroslav@1890
    99
     * This is an implementation of a concurrent lock-free deque
jaroslav@1890
   100
     * supporting interior removes but not interior insertions, as
jaroslav@1890
   101
     * required to support the entire Deque interface.
jaroslav@1890
   102
     *
jaroslav@1890
   103
     * We extend the techniques developed for ConcurrentLinkedQueue and
jaroslav@1890
   104
     * LinkedTransferQueue (see the internal docs for those classes).
jaroslav@1890
   105
     * Understanding the ConcurrentLinkedQueue implementation is a
jaroslav@1890
   106
     * prerequisite for understanding the implementation of this class.
jaroslav@1890
   107
     *
jaroslav@1890
   108
     * The data structure is a symmetrical doubly-linked "GC-robust"
jaroslav@1890
   109
     * linked list of nodes.  We minimize the number of volatile writes
jaroslav@1890
   110
     * using two techniques: advancing multiple hops with a single CAS
jaroslav@1890
   111
     * and mixing volatile and non-volatile writes of the same memory
jaroslav@1890
   112
     * locations.
jaroslav@1890
   113
     *
jaroslav@1890
   114
     * A node contains the expected E ("item") and links to predecessor
jaroslav@1890
   115
     * ("prev") and successor ("next") nodes:
jaroslav@1890
   116
     *
jaroslav@1890
   117
     * class Node<E> { volatile Node<E> prev, next; volatile E item; }
jaroslav@1890
   118
     *
jaroslav@1890
   119
     * A node p is considered "live" if it contains a non-null item
jaroslav@1890
   120
     * (p.item != null).  When an item is CASed to null, the item is
jaroslav@1890
   121
     * atomically logically deleted from the collection.
jaroslav@1890
   122
     *
jaroslav@1890
   123
     * At any time, there is precisely one "first" node with a null
jaroslav@1890
   124
     * prev reference that terminates any chain of prev references
jaroslav@1890
   125
     * starting at a live node.  Similarly there is precisely one
jaroslav@1890
   126
     * "last" node terminating any chain of next references starting at
jaroslav@1890
   127
     * a live node.  The "first" and "last" nodes may or may not be live.
jaroslav@1890
   128
     * The "first" and "last" nodes are always mutually reachable.
jaroslav@1890
   129
     *
jaroslav@1890
   130
     * A new element is added atomically by CASing the null prev or
jaroslav@1890
   131
     * next reference in the first or last node to a fresh node
jaroslav@1890
   132
     * containing the element.  The element's node atomically becomes
jaroslav@1890
   133
     * "live" at that point.
jaroslav@1890
   134
     *
jaroslav@1890
   135
     * A node is considered "active" if it is a live node, or the
jaroslav@1890
   136
     * first or last node.  Active nodes cannot be unlinked.
jaroslav@1890
   137
     *
jaroslav@1890
   138
     * A "self-link" is a next or prev reference that is the same node:
jaroslav@1890
   139
     *   p.prev == p  or  p.next == p
jaroslav@1890
   140
     * Self-links are used in the node unlinking process.  Active nodes
jaroslav@1890
   141
     * never have self-links.
jaroslav@1890
   142
     *
jaroslav@1890
   143
     * A node p is active if and only if:
jaroslav@1890
   144
     *
jaroslav@1890
   145
     * p.item != null ||
jaroslav@1890
   146
     * (p.prev == null && p.next != p) ||
jaroslav@1890
   147
     * (p.next == null && p.prev != p)
jaroslav@1890
   148
     *
jaroslav@1890
   149
     * The deque object has two node references, "head" and "tail".
jaroslav@1890
   150
     * The head and tail are only approximations to the first and last
jaroslav@1890
   151
     * nodes of the deque.  The first node can always be found by
jaroslav@1890
   152
     * following prev pointers from head; likewise for tail.  However,
jaroslav@1890
   153
     * it is permissible for head and tail to be referring to deleted
jaroslav@1890
   154
     * nodes that have been unlinked and so may not be reachable from
jaroslav@1890
   155
     * any live node.
jaroslav@1890
   156
     *
jaroslav@1890
   157
     * There are 3 stages of node deletion;
jaroslav@1890
   158
     * "logical deletion", "unlinking", and "gc-unlinking".
jaroslav@1890
   159
     *
jaroslav@1890
   160
     * 1. "logical deletion" by CASing item to null atomically removes
jaroslav@1890
   161
     * the element from the collection, and makes the containing node
jaroslav@1890
   162
     * eligible for unlinking.
jaroslav@1890
   163
     *
jaroslav@1890
   164
     * 2. "unlinking" makes a deleted node unreachable from active
jaroslav@1890
   165
     * nodes, and thus eventually reclaimable by GC.  Unlinked nodes
jaroslav@1890
   166
     * may remain reachable indefinitely from an iterator.
jaroslav@1890
   167
     *
jaroslav@1890
   168
     * Physical node unlinking is merely an optimization (albeit a
jaroslav@1890
   169
     * critical one), and so can be performed at our convenience.  At
jaroslav@1890
   170
     * any time, the set of live nodes maintained by prev and next
jaroslav@1890
   171
     * links are identical, that is, the live nodes found via next
jaroslav@1890
   172
     * links from the first node is equal to the elements found via
jaroslav@1890
   173
     * prev links from the last node.  However, this is not true for
jaroslav@1890
   174
     * nodes that have already been logically deleted - such nodes may
jaroslav@1890
   175
     * be reachable in one direction only.
jaroslav@1890
   176
     *
jaroslav@1890
   177
     * 3. "gc-unlinking" takes unlinking further by making active
jaroslav@1890
   178
     * nodes unreachable from deleted nodes, making it easier for the
jaroslav@1890
   179
     * GC to reclaim future deleted nodes.  This step makes the data
jaroslav@1890
   180
     * structure "gc-robust", as first described in detail by Boehm
jaroslav@1890
   181
     * (http://portal.acm.org/citation.cfm?doid=503272.503282).
jaroslav@1890
   182
     *
jaroslav@1890
   183
     * GC-unlinked nodes may remain reachable indefinitely from an
jaroslav@1890
   184
     * iterator, but unlike unlinked nodes, are never reachable from
jaroslav@1890
   185
     * head or tail.
jaroslav@1890
   186
     *
jaroslav@1890
   187
     * Making the data structure GC-robust will eliminate the risk of
jaroslav@1890
   188
     * unbounded memory retention with conservative GCs and is likely
jaroslav@1890
   189
     * to improve performance with generational GCs.
jaroslav@1890
   190
     *
jaroslav@1890
   191
     * When a node is dequeued at either end, e.g. via poll(), we would
jaroslav@1890
   192
     * like to break any references from the node to active nodes.  We
jaroslav@1890
   193
     * develop further the use of self-links that was very effective in
jaroslav@1890
   194
     * other concurrent collection classes.  The idea is to replace
jaroslav@1890
   195
     * prev and next pointers with special values that are interpreted
jaroslav@1890
   196
     * to mean off-the-list-at-one-end.  These are approximations, but
jaroslav@1890
   197
     * good enough to preserve the properties we want in our
jaroslav@1890
   198
     * traversals, e.g. we guarantee that a traversal will never visit
jaroslav@1890
   199
     * the same element twice, but we don't guarantee whether a
jaroslav@1890
   200
     * traversal that runs out of elements will be able to see more
jaroslav@1890
   201
     * elements later after enqueues at that end.  Doing gc-unlinking
jaroslav@1890
   202
     * safely is particularly tricky, since any node can be in use
jaroslav@1890
   203
     * indefinitely (for example by an iterator).  We must ensure that
jaroslav@1890
   204
     * the nodes pointed at by head/tail never get gc-unlinked, since
jaroslav@1890
   205
     * head/tail are needed to get "back on track" by other nodes that
jaroslav@1890
   206
     * are gc-unlinked.  gc-unlinking accounts for much of the
jaroslav@1890
   207
     * implementation complexity.
jaroslav@1890
   208
     *
jaroslav@1890
   209
     * Since neither unlinking nor gc-unlinking are necessary for
jaroslav@1890
   210
     * correctness, there are many implementation choices regarding
jaroslav@1890
   211
     * frequency (eagerness) of these operations.  Since volatile
jaroslav@1890
   212
     * reads are likely to be much cheaper than CASes, saving CASes by
jaroslav@1890
   213
     * unlinking multiple adjacent nodes at a time may be a win.
jaroslav@1890
   214
     * gc-unlinking can be performed rarely and still be effective,
jaroslav@1890
   215
     * since it is most important that long chains of deleted nodes
jaroslav@1890
   216
     * are occasionally broken.
jaroslav@1890
   217
     *
jaroslav@1890
   218
     * The actual representation we use is that p.next == p means to
jaroslav@1890
   219
     * goto the first node (which in turn is reached by following prev
jaroslav@1890
   220
     * pointers from head), and p.next == null && p.prev == p means
jaroslav@1890
   221
     * that the iteration is at an end and that p is a (static final)
jaroslav@1890
   222
     * dummy node, NEXT_TERMINATOR, and not the last active node.
jaroslav@1890
   223
     * Finishing the iteration when encountering such a TERMINATOR is
jaroslav@1890
   224
     * good enough for read-only traversals, so such traversals can use
jaroslav@1890
   225
     * p.next == null as the termination condition.  When we need to
jaroslav@1890
   226
     * find the last (active) node, for enqueueing a new node, we need
jaroslav@1890
   227
     * to check whether we have reached a TERMINATOR node; if so,
jaroslav@1890
   228
     * restart traversal from tail.
jaroslav@1890
   229
     *
jaroslav@1890
   230
     * The implementation is completely directionally symmetrical,
jaroslav@1890
   231
     * except that most public methods that iterate through the list
jaroslav@1890
   232
     * follow next pointers ("forward" direction).
jaroslav@1890
   233
     *
jaroslav@1890
   234
     * We believe (without full proof) that all single-element deque
jaroslav@1890
   235
     * operations (e.g., addFirst, peekLast, pollLast) are linearizable
jaroslav@1890
   236
     * (see Herlihy and Shavit's book).  However, some combinations of
jaroslav@1890
   237
     * operations are known not to be linearizable.  In particular,
jaroslav@1890
   238
     * when an addFirst(A) is racing with pollFirst() removing B, it is
jaroslav@1890
   239
     * possible for an observer iterating over the elements to observe
jaroslav@1890
   240
     * A B C and subsequently observe A C, even though no interior
jaroslav@1890
   241
     * removes are ever performed.  Nevertheless, iterators behave
jaroslav@1890
   242
     * reasonably, providing the "weakly consistent" guarantees.
jaroslav@1890
   243
     *
jaroslav@1890
   244
     * Empirically, microbenchmarks suggest that this class adds about
jaroslav@1890
   245
     * 40% overhead relative to ConcurrentLinkedQueue, which feels as
jaroslav@1890
   246
     * good as we can hope for.
jaroslav@1890
   247
     */
jaroslav@1890
   248
jaroslav@1890
   249
    private static final long serialVersionUID = 876323262645176354L;
jaroslav@1890
   250
jaroslav@1890
   251
    /**
jaroslav@1890
   252
     * A node from which the first node on list (that is, the unique node p
jaroslav@1890
   253
     * with p.prev == null && p.next != p) can be reached in O(1) time.
jaroslav@1890
   254
     * Invariants:
jaroslav@1890
   255
     * - the first node is always O(1) reachable from head via prev links
jaroslav@1890
   256
     * - all live nodes are reachable from the first node via succ()
jaroslav@1890
   257
     * - head != null
jaroslav@1890
   258
     * - (tmp = head).next != tmp || tmp != head
jaroslav@1890
   259
     * - head is never gc-unlinked (but may be unlinked)
jaroslav@1890
   260
     * Non-invariants:
jaroslav@1890
   261
     * - head.item may or may not be null
jaroslav@1890
   262
     * - head may not be reachable from the first or last node, or from tail
jaroslav@1890
   263
     */
jaroslav@1890
   264
    private transient volatile Node<E> head;
jaroslav@1890
   265
jaroslav@1890
   266
    /**
jaroslav@1890
   267
     * A node from which the last node on list (that is, the unique node p
jaroslav@1890
   268
     * with p.next == null && p.prev != p) can be reached in O(1) time.
jaroslav@1890
   269
     * Invariants:
jaroslav@1890
   270
     * - the last node is always O(1) reachable from tail via next links
jaroslav@1890
   271
     * - all live nodes are reachable from the last node via pred()
jaroslav@1890
   272
     * - tail != null
jaroslav@1890
   273
     * - tail is never gc-unlinked (but may be unlinked)
jaroslav@1890
   274
     * Non-invariants:
jaroslav@1890
   275
     * - tail.item may or may not be null
jaroslav@1890
   276
     * - tail may not be reachable from the first or last node, or from head
jaroslav@1890
   277
     */
jaroslav@1890
   278
    private transient volatile Node<E> tail;
jaroslav@1890
   279
jaroslav@1890
   280
    private static final Node<Object> PREV_TERMINATOR, NEXT_TERMINATOR;
jaroslav@1890
   281
jaroslav@1890
   282
    @SuppressWarnings("unchecked")
jaroslav@1890
   283
    Node<E> prevTerminator() {
jaroslav@1890
   284
        return (Node<E>) PREV_TERMINATOR;
jaroslav@1890
   285
    }
jaroslav@1890
   286
jaroslav@1890
   287
    @SuppressWarnings("unchecked")
jaroslav@1890
   288
    Node<E> nextTerminator() {
jaroslav@1890
   289
        return (Node<E>) NEXT_TERMINATOR;
jaroslav@1890
   290
    }
jaroslav@1890
   291
jaroslav@1890
   292
    static final class Node<E> {
jaroslav@1890
   293
        volatile Node<E> prev;
jaroslav@1890
   294
        volatile E item;
jaroslav@1890
   295
        volatile Node<E> next;
jaroslav@1890
   296
jaroslav@1890
   297
        Node() {  // default constructor for NEXT_TERMINATOR, PREV_TERMINATOR
jaroslav@1890
   298
        }
jaroslav@1890
   299
jaroslav@1890
   300
        /**
jaroslav@1890
   301
         * Constructs a new node.  Uses relaxed write because item can
jaroslav@1890
   302
         * only be seen after publication via casNext or casPrev.
jaroslav@1890
   303
         */
jaroslav@1890
   304
        Node(E item) {
jaroslav@1895
   305
            this.item = item;
jaroslav@1890
   306
        }
jaroslav@1890
   307
jaroslav@1890
   308
        boolean casItem(E cmp, E val) {
jaroslav@1895
   309
            if (item == cmp) {
jaroslav@1895
   310
                item = val;
jaroslav@1895
   311
                return true;
jaroslav@1895
   312
            }
jaroslav@1895
   313
            return false;
jaroslav@1890
   314
        }
jaroslav@1890
   315
jaroslav@1890
   316
        void lazySetNext(Node<E> val) {
jaroslav@1895
   317
            this.next = val;
jaroslav@1890
   318
        }
jaroslav@1890
   319
jaroslav@1890
   320
        boolean casNext(Node<E> cmp, Node<E> val) {
jaroslav@1895
   321
            if (next == cmp) {
jaroslav@1895
   322
                next = val;
jaroslav@1895
   323
                return true;
jaroslav@1895
   324
            }
jaroslav@1895
   325
            return false;
jaroslav@1890
   326
        }
jaroslav@1890
   327
jaroslav@1890
   328
        void lazySetPrev(Node<E> val) {
jaroslav@1895
   329
            this.prev = val;
jaroslav@1890
   330
        }
jaroslav@1890
   331
jaroslav@1890
   332
        boolean casPrev(Node<E> cmp, Node<E> val) {
jaroslav@1895
   333
            if (prev == cmp) {
jaroslav@1895
   334
                prev = val;
jaroslav@1895
   335
                return true;
jaroslav@1890
   336
            }
jaroslav@1895
   337
            return false;
jaroslav@1890
   338
        }
jaroslav@1890
   339
    }
jaroslav@1890
   340
jaroslav@1890
   341
    /**
jaroslav@1890
   342
     * Links e as first element.
jaroslav@1890
   343
     */
jaroslav@1890
   344
    private void linkFirst(E e) {
jaroslav@1890
   345
        checkNotNull(e);
jaroslav@1890
   346
        final Node<E> newNode = new Node<E>(e);
jaroslav@1890
   347
jaroslav@1890
   348
        restartFromHead:
jaroslav@1890
   349
        for (;;)
jaroslav@1890
   350
            for (Node<E> h = head, p = h, q;;) {
jaroslav@1890
   351
                if ((q = p.prev) != null &&
jaroslav@1890
   352
                    (q = (p = q).prev) != null)
jaroslav@1890
   353
                    // Check for head updates every other hop.
jaroslav@1890
   354
                    // If p == q, we are sure to follow head instead.
jaroslav@1890
   355
                    p = (h != (h = head)) ? h : q;
jaroslav@1890
   356
                else if (p.next == p) // PREV_TERMINATOR
jaroslav@1890
   357
                    continue restartFromHead;
jaroslav@1890
   358
                else {
jaroslav@1890
   359
                    // p is first node
jaroslav@1890
   360
                    newNode.lazySetNext(p); // CAS piggyback
jaroslav@1890
   361
                    if (p.casPrev(null, newNode)) {
jaroslav@1890
   362
                        // Successful CAS is the linearization point
jaroslav@1890
   363
                        // for e to become an element of this deque,
jaroslav@1890
   364
                        // and for newNode to become "live".
jaroslav@1890
   365
                        if (p != h) // hop two nodes at a time
jaroslav@1890
   366
                            casHead(h, newNode);  // Failure is OK.
jaroslav@1890
   367
                        return;
jaroslav@1890
   368
                    }
jaroslav@1890
   369
                    // Lost CAS race to another thread; re-read prev
jaroslav@1890
   370
                }
jaroslav@1890
   371
            }
jaroslav@1890
   372
    }
jaroslav@1890
   373
jaroslav@1890
   374
    /**
jaroslav@1890
   375
     * Links e as last element.
jaroslav@1890
   376
     */
jaroslav@1890
   377
    private void linkLast(E e) {
jaroslav@1890
   378
        checkNotNull(e);
jaroslav@1890
   379
        final Node<E> newNode = new Node<E>(e);
jaroslav@1890
   380
jaroslav@1890
   381
        restartFromTail:
jaroslav@1890
   382
        for (;;)
jaroslav@1890
   383
            for (Node<E> t = tail, p = t, q;;) {
jaroslav@1890
   384
                if ((q = p.next) != null &&
jaroslav@1890
   385
                    (q = (p = q).next) != null)
jaroslav@1890
   386
                    // Check for tail updates every other hop.
jaroslav@1890
   387
                    // If p == q, we are sure to follow tail instead.
jaroslav@1890
   388
                    p = (t != (t = tail)) ? t : q;
jaroslav@1890
   389
                else if (p.prev == p) // NEXT_TERMINATOR
jaroslav@1890
   390
                    continue restartFromTail;
jaroslav@1890
   391
                else {
jaroslav@1890
   392
                    // p is last node
jaroslav@1890
   393
                    newNode.lazySetPrev(p); // CAS piggyback
jaroslav@1890
   394
                    if (p.casNext(null, newNode)) {
jaroslav@1890
   395
                        // Successful CAS is the linearization point
jaroslav@1890
   396
                        // for e to become an element of this deque,
jaroslav@1890
   397
                        // and for newNode to become "live".
jaroslav@1890
   398
                        if (p != t) // hop two nodes at a time
jaroslav@1890
   399
                            casTail(t, newNode);  // Failure is OK.
jaroslav@1890
   400
                        return;
jaroslav@1890
   401
                    }
jaroslav@1890
   402
                    // Lost CAS race to another thread; re-read next
jaroslav@1890
   403
                }
jaroslav@1890
   404
            }
jaroslav@1890
   405
    }
jaroslav@1890
   406
jaroslav@1890
   407
    private static final int HOPS = 2;
jaroslav@1890
   408
jaroslav@1890
   409
    /**
jaroslav@1890
   410
     * Unlinks non-null node x.
jaroslav@1890
   411
     */
jaroslav@1890
   412
    void unlink(Node<E> x) {
jaroslav@1890
   413
        // assert x != null;
jaroslav@1890
   414
        // assert x.item == null;
jaroslav@1890
   415
        // assert x != PREV_TERMINATOR;
jaroslav@1890
   416
        // assert x != NEXT_TERMINATOR;
jaroslav@1890
   417
jaroslav@1890
   418
        final Node<E> prev = x.prev;
jaroslav@1890
   419
        final Node<E> next = x.next;
jaroslav@1890
   420
        if (prev == null) {
jaroslav@1890
   421
            unlinkFirst(x, next);
jaroslav@1890
   422
        } else if (next == null) {
jaroslav@1890
   423
            unlinkLast(x, prev);
jaroslav@1890
   424
        } else {
jaroslav@1890
   425
            // Unlink interior node.
jaroslav@1890
   426
            //
jaroslav@1890
   427
            // This is the common case, since a series of polls at the
jaroslav@1890
   428
            // same end will be "interior" removes, except perhaps for
jaroslav@1890
   429
            // the first one, since end nodes cannot be unlinked.
jaroslav@1890
   430
            //
jaroslav@1890
   431
            // At any time, all active nodes are mutually reachable by
jaroslav@1890
   432
            // following a sequence of either next or prev pointers.
jaroslav@1890
   433
            //
jaroslav@1890
   434
            // Our strategy is to find the unique active predecessor
jaroslav@1890
   435
            // and successor of x.  Try to fix up their links so that
jaroslav@1890
   436
            // they point to each other, leaving x unreachable from
jaroslav@1890
   437
            // active nodes.  If successful, and if x has no live
jaroslav@1890
   438
            // predecessor/successor, we additionally try to gc-unlink,
jaroslav@1890
   439
            // leaving active nodes unreachable from x, by rechecking
jaroslav@1890
   440
            // that the status of predecessor and successor are
jaroslav@1890
   441
            // unchanged and ensuring that x is not reachable from
jaroslav@1890
   442
            // tail/head, before setting x's prev/next links to their
jaroslav@1890
   443
            // logical approximate replacements, self/TERMINATOR.
jaroslav@1890
   444
            Node<E> activePred, activeSucc;
jaroslav@1890
   445
            boolean isFirst, isLast;
jaroslav@1890
   446
            int hops = 1;
jaroslav@1890
   447
jaroslav@1890
   448
            // Find active predecessor
jaroslav@1890
   449
            for (Node<E> p = prev; ; ++hops) {
jaroslav@1890
   450
                if (p.item != null) {
jaroslav@1890
   451
                    activePred = p;
jaroslav@1890
   452
                    isFirst = false;
jaroslav@1890
   453
                    break;
jaroslav@1890
   454
                }
jaroslav@1890
   455
                Node<E> q = p.prev;
jaroslav@1890
   456
                if (q == null) {
jaroslav@1890
   457
                    if (p.next == p)
jaroslav@1890
   458
                        return;
jaroslav@1890
   459
                    activePred = p;
jaroslav@1890
   460
                    isFirst = true;
jaroslav@1890
   461
                    break;
jaroslav@1890
   462
                }
jaroslav@1890
   463
                else if (p == q)
jaroslav@1890
   464
                    return;
jaroslav@1890
   465
                else
jaroslav@1890
   466
                    p = q;
jaroslav@1890
   467
            }
jaroslav@1890
   468
jaroslav@1890
   469
            // Find active successor
jaroslav@1890
   470
            for (Node<E> p = next; ; ++hops) {
jaroslav@1890
   471
                if (p.item != null) {
jaroslav@1890
   472
                    activeSucc = p;
jaroslav@1890
   473
                    isLast = false;
jaroslav@1890
   474
                    break;
jaroslav@1890
   475
                }
jaroslav@1890
   476
                Node<E> q = p.next;
jaroslav@1890
   477
                if (q == null) {
jaroslav@1890
   478
                    if (p.prev == p)
jaroslav@1890
   479
                        return;
jaroslav@1890
   480
                    activeSucc = p;
jaroslav@1890
   481
                    isLast = true;
jaroslav@1890
   482
                    break;
jaroslav@1890
   483
                }
jaroslav@1890
   484
                else if (p == q)
jaroslav@1890
   485
                    return;
jaroslav@1890
   486
                else
jaroslav@1890
   487
                    p = q;
jaroslav@1890
   488
            }
jaroslav@1890
   489
jaroslav@1890
   490
            // TODO: better HOP heuristics
jaroslav@1890
   491
            if (hops < HOPS
jaroslav@1890
   492
                // always squeeze out interior deleted nodes
jaroslav@1890
   493
                && (isFirst | isLast))
jaroslav@1890
   494
                return;
jaroslav@1890
   495
jaroslav@1890
   496
            // Squeeze out deleted nodes between activePred and
jaroslav@1890
   497
            // activeSucc, including x.
jaroslav@1890
   498
            skipDeletedSuccessors(activePred);
jaroslav@1890
   499
            skipDeletedPredecessors(activeSucc);
jaroslav@1890
   500
jaroslav@1890
   501
            // Try to gc-unlink, if possible
jaroslav@1890
   502
            if ((isFirst | isLast) &&
jaroslav@1890
   503
jaroslav@1890
   504
                // Recheck expected state of predecessor and successor
jaroslav@1890
   505
                (activePred.next == activeSucc) &&
jaroslav@1890
   506
                (activeSucc.prev == activePred) &&
jaroslav@1890
   507
                (isFirst ? activePred.prev == null : activePred.item != null) &&
jaroslav@1890
   508
                (isLast  ? activeSucc.next == null : activeSucc.item != null)) {
jaroslav@1890
   509
jaroslav@1890
   510
                updateHead(); // Ensure x is not reachable from head
jaroslav@1890
   511
                updateTail(); // Ensure x is not reachable from tail
jaroslav@1890
   512
jaroslav@1890
   513
                // Finally, actually gc-unlink
jaroslav@1890
   514
                x.lazySetPrev(isFirst ? prevTerminator() : x);
jaroslav@1890
   515
                x.lazySetNext(isLast  ? nextTerminator() : x);
jaroslav@1890
   516
            }
jaroslav@1890
   517
        }
jaroslav@1890
   518
    }
jaroslav@1890
   519
jaroslav@1890
   520
    /**
jaroslav@1890
   521
     * Unlinks non-null first node.
jaroslav@1890
   522
     */
jaroslav@1890
   523
    private void unlinkFirst(Node<E> first, Node<E> next) {
jaroslav@1890
   524
        // assert first != null;
jaroslav@1890
   525
        // assert next != null;
jaroslav@1890
   526
        // assert first.item == null;
jaroslav@1890
   527
        for (Node<E> o = null, p = next, q;;) {
jaroslav@1890
   528
            if (p.item != null || (q = p.next) == null) {
jaroslav@1890
   529
                if (o != null && p.prev != p && first.casNext(next, p)) {
jaroslav@1890
   530
                    skipDeletedPredecessors(p);
jaroslav@1890
   531
                    if (first.prev == null &&
jaroslav@1890
   532
                        (p.next == null || p.item != null) &&
jaroslav@1890
   533
                        p.prev == first) {
jaroslav@1890
   534
jaroslav@1890
   535
                        updateHead(); // Ensure o is not reachable from head
jaroslav@1890
   536
                        updateTail(); // Ensure o is not reachable from tail
jaroslav@1890
   537
jaroslav@1890
   538
                        // Finally, actually gc-unlink
jaroslav@1890
   539
                        o.lazySetNext(o);
jaroslav@1890
   540
                        o.lazySetPrev(prevTerminator());
jaroslav@1890
   541
                    }
jaroslav@1890
   542
                }
jaroslav@1890
   543
                return;
jaroslav@1890
   544
            }
jaroslav@1890
   545
            else if (p == q)
jaroslav@1890
   546
                return;
jaroslav@1890
   547
            else {
jaroslav@1890
   548
                o = p;
jaroslav@1890
   549
                p = q;
jaroslav@1890
   550
            }
jaroslav@1890
   551
        }
jaroslav@1890
   552
    }
jaroslav@1890
   553
jaroslav@1890
   554
    /**
jaroslav@1890
   555
     * Unlinks non-null last node.
jaroslav@1890
   556
     */
jaroslav@1890
   557
    private void unlinkLast(Node<E> last, Node<E> prev) {
jaroslav@1890
   558
        // assert last != null;
jaroslav@1890
   559
        // assert prev != null;
jaroslav@1890
   560
        // assert last.item == null;
jaroslav@1890
   561
        for (Node<E> o = null, p = prev, q;;) {
jaroslav@1890
   562
            if (p.item != null || (q = p.prev) == null) {
jaroslav@1890
   563
                if (o != null && p.next != p && last.casPrev(prev, p)) {
jaroslav@1890
   564
                    skipDeletedSuccessors(p);
jaroslav@1890
   565
                    if (last.next == null &&
jaroslav@1890
   566
                        (p.prev == null || p.item != null) &&
jaroslav@1890
   567
                        p.next == last) {
jaroslav@1890
   568
jaroslav@1890
   569
                        updateHead(); // Ensure o is not reachable from head
jaroslav@1890
   570
                        updateTail(); // Ensure o is not reachable from tail
jaroslav@1890
   571
jaroslav@1890
   572
                        // Finally, actually gc-unlink
jaroslav@1890
   573
                        o.lazySetPrev(o);
jaroslav@1890
   574
                        o.lazySetNext(nextTerminator());
jaroslav@1890
   575
                    }
jaroslav@1890
   576
                }
jaroslav@1890
   577
                return;
jaroslav@1890
   578
            }
jaroslav@1890
   579
            else if (p == q)
jaroslav@1890
   580
                return;
jaroslav@1890
   581
            else {
jaroslav@1890
   582
                o = p;
jaroslav@1890
   583
                p = q;
jaroslav@1890
   584
            }
jaroslav@1890
   585
        }
jaroslav@1890
   586
    }
jaroslav@1890
   587
jaroslav@1890
   588
    /**
jaroslav@1890
   589
     * Guarantees that any node which was unlinked before a call to
jaroslav@1890
   590
     * this method will be unreachable from head after it returns.
jaroslav@1890
   591
     * Does not guarantee to eliminate slack, only that head will
jaroslav@1890
   592
     * point to a node that was active while this method was running.
jaroslav@1890
   593
     */
jaroslav@1890
   594
    private final void updateHead() {
jaroslav@1890
   595
        // Either head already points to an active node, or we keep
jaroslav@1890
   596
        // trying to cas it to the first node until it does.
jaroslav@1890
   597
        Node<E> h, p, q;
jaroslav@1890
   598
        restartFromHead:
jaroslav@1890
   599
        while ((h = head).item == null && (p = h.prev) != null) {
jaroslav@1890
   600
            for (;;) {
jaroslav@1890
   601
                if ((q = p.prev) == null ||
jaroslav@1890
   602
                    (q = (p = q).prev) == null) {
jaroslav@1890
   603
                    // It is possible that p is PREV_TERMINATOR,
jaroslav@1890
   604
                    // but if so, the CAS is guaranteed to fail.
jaroslav@1890
   605
                    if (casHead(h, p))
jaroslav@1890
   606
                        return;
jaroslav@1890
   607
                    else
jaroslav@1890
   608
                        continue restartFromHead;
jaroslav@1890
   609
                }
jaroslav@1890
   610
                else if (h != head)
jaroslav@1890
   611
                    continue restartFromHead;
jaroslav@1890
   612
                else
jaroslav@1890
   613
                    p = q;
jaroslav@1890
   614
            }
jaroslav@1890
   615
        }
jaroslav@1890
   616
    }
jaroslav@1890
   617
jaroslav@1890
   618
    /**
jaroslav@1890
   619
     * Guarantees that any node which was unlinked before a call to
jaroslav@1890
   620
     * this method will be unreachable from tail after it returns.
jaroslav@1890
   621
     * Does not guarantee to eliminate slack, only that tail will
jaroslav@1890
   622
     * point to a node that was active while this method was running.
jaroslav@1890
   623
     */
jaroslav@1890
   624
    private final void updateTail() {
jaroslav@1890
   625
        // Either tail already points to an active node, or we keep
jaroslav@1890
   626
        // trying to cas it to the last node until it does.
jaroslav@1890
   627
        Node<E> t, p, q;
jaroslav@1890
   628
        restartFromTail:
jaroslav@1890
   629
        while ((t = tail).item == null && (p = t.next) != null) {
jaroslav@1890
   630
            for (;;) {
jaroslav@1890
   631
                if ((q = p.next) == null ||
jaroslav@1890
   632
                    (q = (p = q).next) == null) {
jaroslav@1890
   633
                    // It is possible that p is NEXT_TERMINATOR,
jaroslav@1890
   634
                    // but if so, the CAS is guaranteed to fail.
jaroslav@1890
   635
                    if (casTail(t, p))
jaroslav@1890
   636
                        return;
jaroslav@1890
   637
                    else
jaroslav@1890
   638
                        continue restartFromTail;
jaroslav@1890
   639
                }
jaroslav@1890
   640
                else if (t != tail)
jaroslav@1890
   641
                    continue restartFromTail;
jaroslav@1890
   642
                else
jaroslav@1890
   643
                    p = q;
jaroslav@1890
   644
            }
jaroslav@1890
   645
        }
jaroslav@1890
   646
    }
jaroslav@1890
   647
jaroslav@1890
   648
    private void skipDeletedPredecessors(Node<E> x) {
jaroslav@1890
   649
        whileActive:
jaroslav@1890
   650
        do {
jaroslav@1890
   651
            Node<E> prev = x.prev;
jaroslav@1890
   652
            // assert prev != null;
jaroslav@1890
   653
            // assert x != NEXT_TERMINATOR;
jaroslav@1890
   654
            // assert x != PREV_TERMINATOR;
jaroslav@1890
   655
            Node<E> p = prev;
jaroslav@1890
   656
            findActive:
jaroslav@1890
   657
            for (;;) {
jaroslav@1890
   658
                if (p.item != null)
jaroslav@1890
   659
                    break findActive;
jaroslav@1890
   660
                Node<E> q = p.prev;
jaroslav@1890
   661
                if (q == null) {
jaroslav@1890
   662
                    if (p.next == p)
jaroslav@1890
   663
                        continue whileActive;
jaroslav@1890
   664
                    break findActive;
jaroslav@1890
   665
                }
jaroslav@1890
   666
                else if (p == q)
jaroslav@1890
   667
                    continue whileActive;
jaroslav@1890
   668
                else
jaroslav@1890
   669
                    p = q;
jaroslav@1890
   670
            }
jaroslav@1890
   671
jaroslav@1890
   672
            // found active CAS target
jaroslav@1890
   673
            if (prev == p || x.casPrev(prev, p))
jaroslav@1890
   674
                return;
jaroslav@1890
   675
jaroslav@1890
   676
        } while (x.item != null || x.next == null);
jaroslav@1890
   677
    }
jaroslav@1890
   678
jaroslav@1890
   679
    private void skipDeletedSuccessors(Node<E> x) {
jaroslav@1890
   680
        whileActive:
jaroslav@1890
   681
        do {
jaroslav@1890
   682
            Node<E> next = x.next;
jaroslav@1890
   683
            // assert next != null;
jaroslav@1890
   684
            // assert x != NEXT_TERMINATOR;
jaroslav@1890
   685
            // assert x != PREV_TERMINATOR;
jaroslav@1890
   686
            Node<E> p = next;
jaroslav@1890
   687
            findActive:
jaroslav@1890
   688
            for (;;) {
jaroslav@1890
   689
                if (p.item != null)
jaroslav@1890
   690
                    break findActive;
jaroslav@1890
   691
                Node<E> q = p.next;
jaroslav@1890
   692
                if (q == null) {
jaroslav@1890
   693
                    if (p.prev == p)
jaroslav@1890
   694
                        continue whileActive;
jaroslav@1890
   695
                    break findActive;
jaroslav@1890
   696
                }
jaroslav@1890
   697
                else if (p == q)
jaroslav@1890
   698
                    continue whileActive;
jaroslav@1890
   699
                else
jaroslav@1890
   700
                    p = q;
jaroslav@1890
   701
            }
jaroslav@1890
   702
jaroslav@1890
   703
            // found active CAS target
jaroslav@1890
   704
            if (next == p || x.casNext(next, p))
jaroslav@1890
   705
                return;
jaroslav@1890
   706
jaroslav@1890
   707
        } while (x.item != null || x.prev == null);
jaroslav@1890
   708
    }
jaroslav@1890
   709
jaroslav@1890
   710
    /**
jaroslav@1890
   711
     * Returns the successor of p, or the first node if p.next has been
jaroslav@1890
   712
     * linked to self, which will only be true if traversing with a
jaroslav@1890
   713
     * stale pointer that is now off the list.
jaroslav@1890
   714
     */
jaroslav@1890
   715
    final Node<E> succ(Node<E> p) {
jaroslav@1890
   716
        // TODO: should we skip deleted nodes here?
jaroslav@1890
   717
        Node<E> q = p.next;
jaroslav@1890
   718
        return (p == q) ? first() : q;
jaroslav@1890
   719
    }
jaroslav@1890
   720
jaroslav@1890
   721
    /**
jaroslav@1890
   722
     * Returns the predecessor of p, or the last node if p.prev has been
jaroslav@1890
   723
     * linked to self, which will only be true if traversing with a
jaroslav@1890
   724
     * stale pointer that is now off the list.
jaroslav@1890
   725
     */
jaroslav@1890
   726
    final Node<E> pred(Node<E> p) {
jaroslav@1890
   727
        Node<E> q = p.prev;
jaroslav@1890
   728
        return (p == q) ? last() : q;
jaroslav@1890
   729
    }
jaroslav@1890
   730
jaroslav@1890
   731
    /**
jaroslav@1890
   732
     * Returns the first node, the unique node p for which:
jaroslav@1890
   733
     *     p.prev == null && p.next != p
jaroslav@1890
   734
     * The returned node may or may not be logically deleted.
jaroslav@1890
   735
     * Guarantees that head is set to the returned node.
jaroslav@1890
   736
     */
jaroslav@1890
   737
    Node<E> first() {
jaroslav@1890
   738
        restartFromHead:
jaroslav@1890
   739
        for (;;)
jaroslav@1890
   740
            for (Node<E> h = head, p = h, q;;) {
jaroslav@1890
   741
                if ((q = p.prev) != null &&
jaroslav@1890
   742
                    (q = (p = q).prev) != null)
jaroslav@1890
   743
                    // Check for head updates every other hop.
jaroslav@1890
   744
                    // If p == q, we are sure to follow head instead.
jaroslav@1890
   745
                    p = (h != (h = head)) ? h : q;
jaroslav@1890
   746
                else if (p == h
jaroslav@1890
   747
                         // It is possible that p is PREV_TERMINATOR,
jaroslav@1890
   748
                         // but if so, the CAS is guaranteed to fail.
jaroslav@1890
   749
                         || casHead(h, p))
jaroslav@1890
   750
                    return p;
jaroslav@1890
   751
                else
jaroslav@1890
   752
                    continue restartFromHead;
jaroslav@1890
   753
            }
jaroslav@1890
   754
    }
jaroslav@1890
   755
jaroslav@1890
   756
    /**
jaroslav@1890
   757
     * Returns the last node, the unique node p for which:
jaroslav@1890
   758
     *     p.next == null && p.prev != p
jaroslav@1890
   759
     * The returned node may or may not be logically deleted.
jaroslav@1890
   760
     * Guarantees that tail is set to the returned node.
jaroslav@1890
   761
     */
jaroslav@1890
   762
    Node<E> last() {
jaroslav@1890
   763
        restartFromTail:
jaroslav@1890
   764
        for (;;)
jaroslav@1890
   765
            for (Node<E> t = tail, p = t, q;;) {
jaroslav@1890
   766
                if ((q = p.next) != null &&
jaroslav@1890
   767
                    (q = (p = q).next) != null)
jaroslav@1890
   768
                    // Check for tail updates every other hop.
jaroslav@1890
   769
                    // If p == q, we are sure to follow tail instead.
jaroslav@1890
   770
                    p = (t != (t = tail)) ? t : q;
jaroslav@1890
   771
                else if (p == t
jaroslav@1890
   772
                         // It is possible that p is NEXT_TERMINATOR,
jaroslav@1890
   773
                         // but if so, the CAS is guaranteed to fail.
jaroslav@1890
   774
                         || casTail(t, p))
jaroslav@1890
   775
                    return p;
jaroslav@1890
   776
                else
jaroslav@1890
   777
                    continue restartFromTail;
jaroslav@1890
   778
            }
jaroslav@1890
   779
    }
jaroslav@1890
   780
jaroslav@1890
   781
    // Minor convenience utilities
jaroslav@1890
   782
jaroslav@1890
   783
    /**
jaroslav@1890
   784
     * Throws NullPointerException if argument is null.
jaroslav@1890
   785
     *
jaroslav@1890
   786
     * @param v the element
jaroslav@1890
   787
     */
jaroslav@1890
   788
    private static void checkNotNull(Object v) {
jaroslav@1890
   789
        if (v == null)
jaroslav@1890
   790
            throw new NullPointerException();
jaroslav@1890
   791
    }
jaroslav@1890
   792
jaroslav@1890
   793
    /**
jaroslav@1890
   794
     * Returns element unless it is null, in which case throws
jaroslav@1890
   795
     * NoSuchElementException.
jaroslav@1890
   796
     *
jaroslav@1890
   797
     * @param v the element
jaroslav@1890
   798
     * @return the element
jaroslav@1890
   799
     */
jaroslav@1890
   800
    private E screenNullResult(E v) {
jaroslav@1890
   801
        if (v == null)
jaroslav@1890
   802
            throw new NoSuchElementException();
jaroslav@1890
   803
        return v;
jaroslav@1890
   804
    }
jaroslav@1890
   805
jaroslav@1890
   806
    /**
jaroslav@1890
   807
     * Creates an array list and fills it with elements of this list.
jaroslav@1890
   808
     * Used by toArray.
jaroslav@1890
   809
     *
jaroslav@1890
   810
     * @return the arrayList
jaroslav@1890
   811
     */
jaroslav@1890
   812
    private ArrayList<E> toArrayList() {
jaroslav@1890
   813
        ArrayList<E> list = new ArrayList<E>();
jaroslav@1890
   814
        for (Node<E> p = first(); p != null; p = succ(p)) {
jaroslav@1890
   815
            E item = p.item;
jaroslav@1890
   816
            if (item != null)
jaroslav@1890
   817
                list.add(item);
jaroslav@1890
   818
        }
jaroslav@1890
   819
        return list;
jaroslav@1890
   820
    }
jaroslav@1890
   821
jaroslav@1890
   822
    /**
jaroslav@1890
   823
     * Constructs an empty deque.
jaroslav@1890
   824
     */
jaroslav@1890
   825
    public ConcurrentLinkedDeque() {
jaroslav@1890
   826
        head = tail = new Node<E>(null);
jaroslav@1890
   827
    }
jaroslav@1890
   828
jaroslav@1890
   829
    /**
jaroslav@1890
   830
     * Constructs a deque initially containing the elements of
jaroslav@1890
   831
     * the given collection, added in traversal order of the
jaroslav@1890
   832
     * collection's iterator.
jaroslav@1890
   833
     *
jaroslav@1890
   834
     * @param c the collection of elements to initially contain
jaroslav@1890
   835
     * @throws NullPointerException if the specified collection or any
jaroslav@1890
   836
     *         of its elements are null
jaroslav@1890
   837
     */
jaroslav@1890
   838
    public ConcurrentLinkedDeque(Collection<? extends E> c) {
jaroslav@1890
   839
        // Copy c into a private chain of Nodes
jaroslav@1890
   840
        Node<E> h = null, t = null;
jaroslav@1890
   841
        for (E e : c) {
jaroslav@1890
   842
            checkNotNull(e);
jaroslav@1890
   843
            Node<E> newNode = new Node<E>(e);
jaroslav@1890
   844
            if (h == null)
jaroslav@1890
   845
                h = t = newNode;
jaroslav@1890
   846
            else {
jaroslav@1890
   847
                t.lazySetNext(newNode);
jaroslav@1890
   848
                newNode.lazySetPrev(t);
jaroslav@1890
   849
                t = newNode;
jaroslav@1890
   850
            }
jaroslav@1890
   851
        }
jaroslav@1890
   852
        initHeadTail(h, t);
jaroslav@1890
   853
    }
jaroslav@1890
   854
jaroslav@1890
   855
    /**
jaroslav@1890
   856
     * Initializes head and tail, ensuring invariants hold.
jaroslav@1890
   857
     */
jaroslav@1890
   858
    private void initHeadTail(Node<E> h, Node<E> t) {
jaroslav@1890
   859
        if (h == t) {
jaroslav@1890
   860
            if (h == null)
jaroslav@1890
   861
                h = t = new Node<E>(null);
jaroslav@1890
   862
            else {
jaroslav@1890
   863
                // Avoid edge case of a single Node with non-null item.
jaroslav@1890
   864
                Node<E> newNode = new Node<E>(null);
jaroslav@1890
   865
                t.lazySetNext(newNode);
jaroslav@1890
   866
                newNode.lazySetPrev(t);
jaroslav@1890
   867
                t = newNode;
jaroslav@1890
   868
            }
jaroslav@1890
   869
        }
jaroslav@1890
   870
        head = h;
jaroslav@1890
   871
        tail = t;
jaroslav@1890
   872
    }
jaroslav@1890
   873
jaroslav@1890
   874
    /**
jaroslav@1890
   875
     * Inserts the specified element at the front of this deque.
jaroslav@1890
   876
     * As the deque is unbounded, this method will never throw
jaroslav@1890
   877
     * {@link IllegalStateException}.
jaroslav@1890
   878
     *
jaroslav@1890
   879
     * @throws NullPointerException if the specified element is null
jaroslav@1890
   880
     */
jaroslav@1890
   881
    public void addFirst(E e) {
jaroslav@1890
   882
        linkFirst(e);
jaroslav@1890
   883
    }
jaroslav@1890
   884
jaroslav@1890
   885
    /**
jaroslav@1890
   886
     * Inserts the specified element at the end of this deque.
jaroslav@1890
   887
     * As the deque is unbounded, this method will never throw
jaroslav@1890
   888
     * {@link IllegalStateException}.
jaroslav@1890
   889
     *
jaroslav@1890
   890
     * <p>This method is equivalent to {@link #add}.
jaroslav@1890
   891
     *
jaroslav@1890
   892
     * @throws NullPointerException if the specified element is null
jaroslav@1890
   893
     */
jaroslav@1890
   894
    public void addLast(E e) {
jaroslav@1890
   895
        linkLast(e);
jaroslav@1890
   896
    }
jaroslav@1890
   897
jaroslav@1890
   898
    /**
jaroslav@1890
   899
     * Inserts the specified element at the front of this deque.
jaroslav@1890
   900
     * As the deque is unbounded, this method will never return {@code false}.
jaroslav@1890
   901
     *
jaroslav@1890
   902
     * @return {@code true} (as specified by {@link Deque#offerFirst})
jaroslav@1890
   903
     * @throws NullPointerException if the specified element is null
jaroslav@1890
   904
     */
jaroslav@1890
   905
    public boolean offerFirst(E e) {
jaroslav@1890
   906
        linkFirst(e);
jaroslav@1890
   907
        return true;
jaroslav@1890
   908
    }
jaroslav@1890
   909
jaroslav@1890
   910
    /**
jaroslav@1890
   911
     * Inserts the specified element at the end of this deque.
jaroslav@1890
   912
     * As the deque is unbounded, this method will never return {@code false}.
jaroslav@1890
   913
     *
jaroslav@1890
   914
     * <p>This method is equivalent to {@link #add}.
jaroslav@1890
   915
     *
jaroslav@1890
   916
     * @return {@code true} (as specified by {@link Deque#offerLast})
jaroslav@1890
   917
     * @throws NullPointerException if the specified element is null
jaroslav@1890
   918
     */
jaroslav@1890
   919
    public boolean offerLast(E e) {
jaroslav@1890
   920
        linkLast(e);
jaroslav@1890
   921
        return true;
jaroslav@1890
   922
    }
jaroslav@1890
   923
jaroslav@1890
   924
    public E peekFirst() {
jaroslav@1890
   925
        for (Node<E> p = first(); p != null; p = succ(p)) {
jaroslav@1890
   926
            E item = p.item;
jaroslav@1890
   927
            if (item != null)
jaroslav@1890
   928
                return item;
jaroslav@1890
   929
        }
jaroslav@1890
   930
        return null;
jaroslav@1890
   931
    }
jaroslav@1890
   932
jaroslav@1890
   933
    public E peekLast() {
jaroslav@1890
   934
        for (Node<E> p = last(); p != null; p = pred(p)) {
jaroslav@1890
   935
            E item = p.item;
jaroslav@1890
   936
            if (item != null)
jaroslav@1890
   937
                return item;
jaroslav@1890
   938
        }
jaroslav@1890
   939
        return null;
jaroslav@1890
   940
    }
jaroslav@1890
   941
jaroslav@1890
   942
    /**
jaroslav@1890
   943
     * @throws NoSuchElementException {@inheritDoc}
jaroslav@1890
   944
     */
jaroslav@1890
   945
    public E getFirst() {
jaroslav@1890
   946
        return screenNullResult(peekFirst());
jaroslav@1890
   947
    }
jaroslav@1890
   948
jaroslav@1890
   949
    /**
jaroslav@1890
   950
     * @throws NoSuchElementException {@inheritDoc}
jaroslav@1890
   951
     */
jaroslav@1890
   952
    public E getLast() {
jaroslav@1890
   953
        return screenNullResult(peekLast());
jaroslav@1890
   954
    }
jaroslav@1890
   955
jaroslav@1890
   956
    public E pollFirst() {
jaroslav@1890
   957
        for (Node<E> p = first(); p != null; p = succ(p)) {
jaroslav@1890
   958
            E item = p.item;
jaroslav@1890
   959
            if (item != null && p.casItem(item, null)) {
jaroslav@1890
   960
                unlink(p);
jaroslav@1890
   961
                return item;
jaroslav@1890
   962
            }
jaroslav@1890
   963
        }
jaroslav@1890
   964
        return null;
jaroslav@1890
   965
    }
jaroslav@1890
   966
jaroslav@1890
   967
    public E pollLast() {
jaroslav@1890
   968
        for (Node<E> p = last(); p != null; p = pred(p)) {
jaroslav@1890
   969
            E item = p.item;
jaroslav@1890
   970
            if (item != null && p.casItem(item, null)) {
jaroslav@1890
   971
                unlink(p);
jaroslav@1890
   972
                return item;
jaroslav@1890
   973
            }
jaroslav@1890
   974
        }
jaroslav@1890
   975
        return null;
jaroslav@1890
   976
    }
jaroslav@1890
   977
jaroslav@1890
   978
    /**
jaroslav@1890
   979
     * @throws NoSuchElementException {@inheritDoc}
jaroslav@1890
   980
     */
jaroslav@1890
   981
    public E removeFirst() {
jaroslav@1890
   982
        return screenNullResult(pollFirst());
jaroslav@1890
   983
    }
jaroslav@1890
   984
jaroslav@1890
   985
    /**
jaroslav@1890
   986
     * @throws NoSuchElementException {@inheritDoc}
jaroslav@1890
   987
     */
jaroslav@1890
   988
    public E removeLast() {
jaroslav@1890
   989
        return screenNullResult(pollLast());
jaroslav@1890
   990
    }
jaroslav@1890
   991
jaroslav@1890
   992
    // *** Queue and stack methods ***
jaroslav@1890
   993
jaroslav@1890
   994
    /**
jaroslav@1890
   995
     * Inserts the specified element at the tail of this deque.
jaroslav@1890
   996
     * As the deque is unbounded, this method will never return {@code false}.
jaroslav@1890
   997
     *
jaroslav@1890
   998
     * @return {@code true} (as specified by {@link Queue#offer})
jaroslav@1890
   999
     * @throws NullPointerException if the specified element is null
jaroslav@1890
  1000
     */
jaroslav@1890
  1001
    public boolean offer(E e) {
jaroslav@1890
  1002
        return offerLast(e);
jaroslav@1890
  1003
    }
jaroslav@1890
  1004
jaroslav@1890
  1005
    /**
jaroslav@1890
  1006
     * Inserts the specified element at the tail of this deque.
jaroslav@1890
  1007
     * As the deque is unbounded, this method will never throw
jaroslav@1890
  1008
     * {@link IllegalStateException} or return {@code false}.
jaroslav@1890
  1009
     *
jaroslav@1890
  1010
     * @return {@code true} (as specified by {@link Collection#add})
jaroslav@1890
  1011
     * @throws NullPointerException if the specified element is null
jaroslav@1890
  1012
     */
jaroslav@1890
  1013
    public boolean add(E e) {
jaroslav@1890
  1014
        return offerLast(e);
jaroslav@1890
  1015
    }
jaroslav@1890
  1016
jaroslav@1890
  1017
    public E poll()           { return pollFirst(); }
jaroslav@1890
  1018
    public E remove()         { return removeFirst(); }
jaroslav@1890
  1019
    public E peek()           { return peekFirst(); }
jaroslav@1890
  1020
    public E element()        { return getFirst(); }
jaroslav@1890
  1021
    public void push(E e)     { addFirst(e); }
jaroslav@1890
  1022
    public E pop()            { return removeFirst(); }
jaroslav@1890
  1023
jaroslav@1890
  1024
    /**
jaroslav@1890
  1025
     * Removes the first element {@code e} such that
jaroslav@1890
  1026
     * {@code o.equals(e)}, if such an element exists in this deque.
jaroslav@1890
  1027
     * If the deque does not contain the element, it is unchanged.
jaroslav@1890
  1028
     *
jaroslav@1890
  1029
     * @param o element to be removed from this deque, if present
jaroslav@1890
  1030
     * @return {@code true} if the deque contained the specified element
jaroslav@1890
  1031
     * @throws NullPointerException if the specified element is null
jaroslav@1890
  1032
     */
jaroslav@1890
  1033
    public boolean removeFirstOccurrence(Object o) {
jaroslav@1890
  1034
        checkNotNull(o);
jaroslav@1890
  1035
        for (Node<E> p = first(); p != null; p = succ(p)) {
jaroslav@1890
  1036
            E item = p.item;
jaroslav@1890
  1037
            if (item != null && o.equals(item) && p.casItem(item, null)) {
jaroslav@1890
  1038
                unlink(p);
jaroslav@1890
  1039
                return true;
jaroslav@1890
  1040
            }
jaroslav@1890
  1041
        }
jaroslav@1890
  1042
        return false;
jaroslav@1890
  1043
    }
jaroslav@1890
  1044
jaroslav@1890
  1045
    /**
jaroslav@1890
  1046
     * Removes the last element {@code e} such that
jaroslav@1890
  1047
     * {@code o.equals(e)}, if such an element exists in this deque.
jaroslav@1890
  1048
     * If the deque does not contain the element, it is unchanged.
jaroslav@1890
  1049
     *
jaroslav@1890
  1050
     * @param o element to be removed from this deque, if present
jaroslav@1890
  1051
     * @return {@code true} if the deque contained the specified element
jaroslav@1890
  1052
     * @throws NullPointerException if the specified element is null
jaroslav@1890
  1053
     */
jaroslav@1890
  1054
    public boolean removeLastOccurrence(Object o) {
jaroslav@1890
  1055
        checkNotNull(o);
jaroslav@1890
  1056
        for (Node<E> p = last(); p != null; p = pred(p)) {
jaroslav@1890
  1057
            E item = p.item;
jaroslav@1890
  1058
            if (item != null && o.equals(item) && p.casItem(item, null)) {
jaroslav@1890
  1059
                unlink(p);
jaroslav@1890
  1060
                return true;
jaroslav@1890
  1061
            }
jaroslav@1890
  1062
        }
jaroslav@1890
  1063
        return false;
jaroslav@1890
  1064
    }
jaroslav@1890
  1065
jaroslav@1890
  1066
    /**
jaroslav@1890
  1067
     * Returns {@code true} if this deque contains at least one
jaroslav@1890
  1068
     * element {@code e} such that {@code o.equals(e)}.
jaroslav@1890
  1069
     *
jaroslav@1890
  1070
     * @param o element whose presence in this deque is to be tested
jaroslav@1890
  1071
     * @return {@code true} if this deque contains the specified element
jaroslav@1890
  1072
     */
jaroslav@1890
  1073
    public boolean contains(Object o) {
jaroslav@1890
  1074
        if (o == null) return false;
jaroslav@1890
  1075
        for (Node<E> p = first(); p != null; p = succ(p)) {
jaroslav@1890
  1076
            E item = p.item;
jaroslav@1890
  1077
            if (item != null && o.equals(item))
jaroslav@1890
  1078
                return true;
jaroslav@1890
  1079
        }
jaroslav@1890
  1080
        return false;
jaroslav@1890
  1081
    }
jaroslav@1890
  1082
jaroslav@1890
  1083
    /**
jaroslav@1890
  1084
     * Returns {@code true} if this collection contains no elements.
jaroslav@1890
  1085
     *
jaroslav@1890
  1086
     * @return {@code true} if this collection contains no elements
jaroslav@1890
  1087
     */
jaroslav@1890
  1088
    public boolean isEmpty() {
jaroslav@1890
  1089
        return peekFirst() == null;
jaroslav@1890
  1090
    }
jaroslav@1890
  1091
jaroslav@1890
  1092
    /**
jaroslav@1890
  1093
     * Returns the number of elements in this deque.  If this deque
jaroslav@1890
  1094
     * contains more than {@code Integer.MAX_VALUE} elements, it
jaroslav@1890
  1095
     * returns {@code Integer.MAX_VALUE}.
jaroslav@1890
  1096
     *
jaroslav@1890
  1097
     * <p>Beware that, unlike in most collections, this method is
jaroslav@1890
  1098
     * <em>NOT</em> a constant-time operation. Because of the
jaroslav@1890
  1099
     * asynchronous nature of these deques, determining the current
jaroslav@1890
  1100
     * number of elements requires traversing them all to count them.
jaroslav@1890
  1101
     * Additionally, it is possible for the size to change during
jaroslav@1890
  1102
     * execution of this method, in which case the returned result
jaroslav@1890
  1103
     * will be inaccurate. Thus, this method is typically not very
jaroslav@1890
  1104
     * useful in concurrent applications.
jaroslav@1890
  1105
     *
jaroslav@1890
  1106
     * @return the number of elements in this deque
jaroslav@1890
  1107
     */
jaroslav@1890
  1108
    public int size() {
jaroslav@1890
  1109
        int count = 0;
jaroslav@1890
  1110
        for (Node<E> p = first(); p != null; p = succ(p))
jaroslav@1890
  1111
            if (p.item != null)
jaroslav@1890
  1112
                // Collection.size() spec says to max out
jaroslav@1890
  1113
                if (++count == Integer.MAX_VALUE)
jaroslav@1890
  1114
                    break;
jaroslav@1890
  1115
        return count;
jaroslav@1890
  1116
    }
jaroslav@1890
  1117
jaroslav@1890
  1118
    /**
jaroslav@1890
  1119
     * Removes the first element {@code e} such that
jaroslav@1890
  1120
     * {@code o.equals(e)}, if such an element exists in this deque.
jaroslav@1890
  1121
     * If the deque does not contain the element, it is unchanged.
jaroslav@1890
  1122
     *
jaroslav@1890
  1123
     * @param o element to be removed from this deque, if present
jaroslav@1890
  1124
     * @return {@code true} if the deque contained the specified element
jaroslav@1890
  1125
     * @throws NullPointerException if the specified element is null
jaroslav@1890
  1126
     */
jaroslav@1890
  1127
    public boolean remove(Object o) {
jaroslav@1890
  1128
        return removeFirstOccurrence(o);
jaroslav@1890
  1129
    }
jaroslav@1890
  1130
jaroslav@1890
  1131
    /**
jaroslav@1890
  1132
     * Appends all of the elements in the specified collection to the end of
jaroslav@1890
  1133
     * this deque, in the order that they are returned by the specified
jaroslav@1890
  1134
     * collection's iterator.  Attempts to {@code addAll} of a deque to
jaroslav@1890
  1135
     * itself result in {@code IllegalArgumentException}.
jaroslav@1890
  1136
     *
jaroslav@1890
  1137
     * @param c the elements to be inserted into this deque
jaroslav@1890
  1138
     * @return {@code true} if this deque changed as a result of the call
jaroslav@1890
  1139
     * @throws NullPointerException if the specified collection or any
jaroslav@1890
  1140
     *         of its elements are null
jaroslav@1890
  1141
     * @throws IllegalArgumentException if the collection is this deque
jaroslav@1890
  1142
     */
jaroslav@1890
  1143
    public boolean addAll(Collection<? extends E> c) {
jaroslav@1890
  1144
        if (c == this)
jaroslav@1890
  1145
            // As historically specified in AbstractQueue#addAll
jaroslav@1890
  1146
            throw new IllegalArgumentException();
jaroslav@1890
  1147
jaroslav@1890
  1148
        // Copy c into a private chain of Nodes
jaroslav@1890
  1149
        Node<E> beginningOfTheEnd = null, last = null;
jaroslav@1890
  1150
        for (E e : c) {
jaroslav@1890
  1151
            checkNotNull(e);
jaroslav@1890
  1152
            Node<E> newNode = new Node<E>(e);
jaroslav@1890
  1153
            if (beginningOfTheEnd == null)
jaroslav@1890
  1154
                beginningOfTheEnd = last = newNode;
jaroslav@1890
  1155
            else {
jaroslav@1890
  1156
                last.lazySetNext(newNode);
jaroslav@1890
  1157
                newNode.lazySetPrev(last);
jaroslav@1890
  1158
                last = newNode;
jaroslav@1890
  1159
            }
jaroslav@1890
  1160
        }
jaroslav@1890
  1161
        if (beginningOfTheEnd == null)
jaroslav@1890
  1162
            return false;
jaroslav@1890
  1163
jaroslav@1890
  1164
        // Atomically append the chain at the tail of this collection
jaroslav@1890
  1165
        restartFromTail:
jaroslav@1890
  1166
        for (;;)
jaroslav@1890
  1167
            for (Node<E> t = tail, p = t, q;;) {
jaroslav@1890
  1168
                if ((q = p.next) != null &&
jaroslav@1890
  1169
                    (q = (p = q).next) != null)
jaroslav@1890
  1170
                    // Check for tail updates every other hop.
jaroslav@1890
  1171
                    // If p == q, we are sure to follow tail instead.
jaroslav@1890
  1172
                    p = (t != (t = tail)) ? t : q;
jaroslav@1890
  1173
                else if (p.prev == p) // NEXT_TERMINATOR
jaroslav@1890
  1174
                    continue restartFromTail;
jaroslav@1890
  1175
                else {
jaroslav@1890
  1176
                    // p is last node
jaroslav@1890
  1177
                    beginningOfTheEnd.lazySetPrev(p); // CAS piggyback
jaroslav@1890
  1178
                    if (p.casNext(null, beginningOfTheEnd)) {
jaroslav@1890
  1179
                        // Successful CAS is the linearization point
jaroslav@1890
  1180
                        // for all elements to be added to this deque.
jaroslav@1890
  1181
                        if (!casTail(t, last)) {
jaroslav@1890
  1182
                            // Try a little harder to update tail,
jaroslav@1890
  1183
                            // since we may be adding many elements.
jaroslav@1890
  1184
                            t = tail;
jaroslav@1890
  1185
                            if (last.next == null)
jaroslav@1890
  1186
                                casTail(t, last);
jaroslav@1890
  1187
                        }
jaroslav@1890
  1188
                        return true;
jaroslav@1890
  1189
                    }
jaroslav@1890
  1190
                    // Lost CAS race to another thread; re-read next
jaroslav@1890
  1191
                }
jaroslav@1890
  1192
            }
jaroslav@1890
  1193
    }
jaroslav@1890
  1194
jaroslav@1890
  1195
    /**
jaroslav@1890
  1196
     * Removes all of the elements from this deque.
jaroslav@1890
  1197
     */
jaroslav@1890
  1198
    public void clear() {
jaroslav@1890
  1199
        while (pollFirst() != null)
jaroslav@1890
  1200
            ;
jaroslav@1890
  1201
    }
jaroslav@1890
  1202
jaroslav@1890
  1203
    /**
jaroslav@1890
  1204
     * Returns an array containing all of the elements in this deque, in
jaroslav@1890
  1205
     * proper sequence (from first to last element).
jaroslav@1890
  1206
     *
jaroslav@1890
  1207
     * <p>The returned array will be "safe" in that no references to it are
jaroslav@1890
  1208
     * maintained by this deque.  (In other words, this method must allocate
jaroslav@1890
  1209
     * a new array).  The caller is thus free to modify the returned array.
jaroslav@1890
  1210
     *
jaroslav@1890
  1211
     * <p>This method acts as bridge between array-based and collection-based
jaroslav@1890
  1212
     * APIs.
jaroslav@1890
  1213
     *
jaroslav@1890
  1214
     * @return an array containing all of the elements in this deque
jaroslav@1890
  1215
     */
jaroslav@1890
  1216
    public Object[] toArray() {
jaroslav@1890
  1217
        return toArrayList().toArray();
jaroslav@1890
  1218
    }
jaroslav@1890
  1219
jaroslav@1890
  1220
    /**
jaroslav@1890
  1221
     * Returns an array containing all of the elements in this deque,
jaroslav@1890
  1222
     * in proper sequence (from first to last element); the runtime
jaroslav@1890
  1223
     * type of the returned array is that of the specified array.  If
jaroslav@1890
  1224
     * the deque fits in the specified array, it is returned therein.
jaroslav@1890
  1225
     * Otherwise, a new array is allocated with the runtime type of
jaroslav@1890
  1226
     * the specified array and the size of this deque.
jaroslav@1890
  1227
     *
jaroslav@1890
  1228
     * <p>If this deque fits in the specified array with room to spare
jaroslav@1890
  1229
     * (i.e., the array has more elements than this deque), the element in
jaroslav@1890
  1230
     * the array immediately following the end of the deque is set to
jaroslav@1890
  1231
     * {@code null}.
jaroslav@1890
  1232
     *
jaroslav@1890
  1233
     * <p>Like the {@link #toArray()} method, this method acts as
jaroslav@1890
  1234
     * bridge between array-based and collection-based APIs.  Further,
jaroslav@1890
  1235
     * this method allows precise control over the runtime type of the
jaroslav@1890
  1236
     * output array, and may, under certain circumstances, be used to
jaroslav@1890
  1237
     * save allocation costs.
jaroslav@1890
  1238
     *
jaroslav@1890
  1239
     * <p>Suppose {@code x} is a deque known to contain only strings.
jaroslav@1890
  1240
     * The following code can be used to dump the deque into a newly
jaroslav@1890
  1241
     * allocated array of {@code String}:
jaroslav@1890
  1242
     *
jaroslav@1890
  1243
     * <pre>
jaroslav@1890
  1244
     *     String[] y = x.toArray(new String[0]);</pre>
jaroslav@1890
  1245
     *
jaroslav@1890
  1246
     * Note that {@code toArray(new Object[0])} is identical in function to
jaroslav@1890
  1247
     * {@code toArray()}.
jaroslav@1890
  1248
     *
jaroslav@1890
  1249
     * @param a the array into which the elements of the deque are to
jaroslav@1890
  1250
     *          be stored, if it is big enough; otherwise, a new array of the
jaroslav@1890
  1251
     *          same runtime type is allocated for this purpose
jaroslav@1890
  1252
     * @return an array containing all of the elements in this deque
jaroslav@1890
  1253
     * @throws ArrayStoreException if the runtime type of the specified array
jaroslav@1890
  1254
     *         is not a supertype of the runtime type of every element in
jaroslav@1890
  1255
     *         this deque
jaroslav@1890
  1256
     * @throws NullPointerException if the specified array is null
jaroslav@1890
  1257
     */
jaroslav@1890
  1258
    public <T> T[] toArray(T[] a) {
jaroslav@1890
  1259
        return toArrayList().toArray(a);
jaroslav@1890
  1260
    }
jaroslav@1890
  1261
jaroslav@1890
  1262
    /**
jaroslav@1890
  1263
     * Returns an iterator over the elements in this deque in proper sequence.
jaroslav@1890
  1264
     * The elements will be returned in order from first (head) to last (tail).
jaroslav@1890
  1265
     *
jaroslav@1890
  1266
     * <p>The returned iterator is a "weakly consistent" iterator that
jaroslav@1890
  1267
     * will never throw {@link java.util.ConcurrentModificationException
jaroslav@1890
  1268
     * ConcurrentModificationException}, and guarantees to traverse
jaroslav@1890
  1269
     * elements as they existed upon construction of the iterator, and
jaroslav@1890
  1270
     * may (but is not guaranteed to) reflect any modifications
jaroslav@1890
  1271
     * subsequent to construction.
jaroslav@1890
  1272
     *
jaroslav@1890
  1273
     * @return an iterator over the elements in this deque in proper sequence
jaroslav@1890
  1274
     */
jaroslav@1890
  1275
    public Iterator<E> iterator() {
jaroslav@1890
  1276
        return new Itr();
jaroslav@1890
  1277
    }
jaroslav@1890
  1278
jaroslav@1890
  1279
    /**
jaroslav@1890
  1280
     * Returns an iterator over the elements in this deque in reverse
jaroslav@1890
  1281
     * sequential order.  The elements will be returned in order from
jaroslav@1890
  1282
     * last (tail) to first (head).
jaroslav@1890
  1283
     *
jaroslav@1890
  1284
     * <p>The returned iterator is a "weakly consistent" iterator that
jaroslav@1890
  1285
     * will never throw {@link java.util.ConcurrentModificationException
jaroslav@1890
  1286
     * ConcurrentModificationException}, and guarantees to traverse
jaroslav@1890
  1287
     * elements as they existed upon construction of the iterator, and
jaroslav@1890
  1288
     * may (but is not guaranteed to) reflect any modifications
jaroslav@1890
  1289
     * subsequent to construction.
jaroslav@1890
  1290
     *
jaroslav@1890
  1291
     * @return an iterator over the elements in this deque in reverse order
jaroslav@1890
  1292
     */
jaroslav@1890
  1293
    public Iterator<E> descendingIterator() {
jaroslav@1890
  1294
        return new DescendingItr();
jaroslav@1890
  1295
    }
jaroslav@1890
  1296
jaroslav@1890
  1297
    private abstract class AbstractItr implements Iterator<E> {
jaroslav@1890
  1298
        /**
jaroslav@1890
  1299
         * Next node to return item for.
jaroslav@1890
  1300
         */
jaroslav@1890
  1301
        private Node<E> nextNode;
jaroslav@1890
  1302
jaroslav@1890
  1303
        /**
jaroslav@1890
  1304
         * nextItem holds on to item fields because once we claim
jaroslav@1890
  1305
         * that an element exists in hasNext(), we must return it in
jaroslav@1890
  1306
         * the following next() call even if it was in the process of
jaroslav@1890
  1307
         * being removed when hasNext() was called.
jaroslav@1890
  1308
         */
jaroslav@1890
  1309
        private E nextItem;
jaroslav@1890
  1310
jaroslav@1890
  1311
        /**
jaroslav@1890
  1312
         * Node returned by most recent call to next. Needed by remove.
jaroslav@1890
  1313
         * Reset to null if this element is deleted by a call to remove.
jaroslav@1890
  1314
         */
jaroslav@1890
  1315
        private Node<E> lastRet;
jaroslav@1890
  1316
jaroslav@1890
  1317
        abstract Node<E> startNode();
jaroslav@1890
  1318
        abstract Node<E> nextNode(Node<E> p);
jaroslav@1890
  1319
jaroslav@1890
  1320
        AbstractItr() {
jaroslav@1890
  1321
            advance();
jaroslav@1890
  1322
        }
jaroslav@1890
  1323
jaroslav@1890
  1324
        /**
jaroslav@1890
  1325
         * Sets nextNode and nextItem to next valid node, or to null
jaroslav@1890
  1326
         * if no such.
jaroslav@1890
  1327
         */
jaroslav@1890
  1328
        private void advance() {
jaroslav@1890
  1329
            lastRet = nextNode;
jaroslav@1890
  1330
jaroslav@1890
  1331
            Node<E> p = (nextNode == null) ? startNode() : nextNode(nextNode);
jaroslav@1890
  1332
            for (;; p = nextNode(p)) {
jaroslav@1890
  1333
                if (p == null) {
jaroslav@1890
  1334
                    // p might be active end or TERMINATOR node; both are OK
jaroslav@1890
  1335
                    nextNode = null;
jaroslav@1890
  1336
                    nextItem = null;
jaroslav@1890
  1337
                    break;
jaroslav@1890
  1338
                }
jaroslav@1890
  1339
                E item = p.item;
jaroslav@1890
  1340
                if (item != null) {
jaroslav@1890
  1341
                    nextNode = p;
jaroslav@1890
  1342
                    nextItem = item;
jaroslav@1890
  1343
                    break;
jaroslav@1890
  1344
                }
jaroslav@1890
  1345
            }
jaroslav@1890
  1346
        }
jaroslav@1890
  1347
jaroslav@1890
  1348
        public boolean hasNext() {
jaroslav@1890
  1349
            return nextItem != null;
jaroslav@1890
  1350
        }
jaroslav@1890
  1351
jaroslav@1890
  1352
        public E next() {
jaroslav@1890
  1353
            E item = nextItem;
jaroslav@1890
  1354
            if (item == null) throw new NoSuchElementException();
jaroslav@1890
  1355
            advance();
jaroslav@1890
  1356
            return item;
jaroslav@1890
  1357
        }
jaroslav@1890
  1358
jaroslav@1890
  1359
        public void remove() {
jaroslav@1890
  1360
            Node<E> l = lastRet;
jaroslav@1890
  1361
            if (l == null) throw new IllegalStateException();
jaroslav@1890
  1362
            l.item = null;
jaroslav@1890
  1363
            unlink(l);
jaroslav@1890
  1364
            lastRet = null;
jaroslav@1890
  1365
        }
jaroslav@1890
  1366
    }
jaroslav@1890
  1367
jaroslav@1890
  1368
    /** Forward iterator */
jaroslav@1890
  1369
    private class Itr extends AbstractItr {
jaroslav@1890
  1370
        Node<E> startNode() { return first(); }
jaroslav@1890
  1371
        Node<E> nextNode(Node<E> p) { return succ(p); }
jaroslav@1890
  1372
    }
jaroslav@1890
  1373
jaroslav@1890
  1374
    /** Descending iterator */
jaroslav@1890
  1375
    private class DescendingItr extends AbstractItr {
jaroslav@1890
  1376
        Node<E> startNode() { return last(); }
jaroslav@1890
  1377
        Node<E> nextNode(Node<E> p) { return pred(p); }
jaroslav@1890
  1378
    }
jaroslav@1890
  1379
jaroslav@1890
  1380
    /**
jaroslav@1890
  1381
     * Saves the state to a stream (that is, serializes it).
jaroslav@1890
  1382
     *
jaroslav@1890
  1383
     * @serialData All of the elements (each an {@code E}) in
jaroslav@1890
  1384
     * the proper order, followed by a null
jaroslav@1890
  1385
     * @param s the stream
jaroslav@1890
  1386
     */
jaroslav@1890
  1387
    private void writeObject(java.io.ObjectOutputStream s)
jaroslav@1890
  1388
        throws java.io.IOException {
jaroslav@1890
  1389
jaroslav@1890
  1390
        // Write out any hidden stuff
jaroslav@1890
  1391
        s.defaultWriteObject();
jaroslav@1890
  1392
jaroslav@1890
  1393
        // Write out all elements in the proper order.
jaroslav@1890
  1394
        for (Node<E> p = first(); p != null; p = succ(p)) {
jaroslav@1890
  1395
            E item = p.item;
jaroslav@1890
  1396
            if (item != null)
jaroslav@1890
  1397
                s.writeObject(item);
jaroslav@1890
  1398
        }
jaroslav@1890
  1399
jaroslav@1890
  1400
        // Use trailing null as sentinel
jaroslav@1890
  1401
        s.writeObject(null);
jaroslav@1890
  1402
    }
jaroslav@1890
  1403
jaroslav@1890
  1404
    /**
jaroslav@1890
  1405
     * Reconstitutes the instance from a stream (that is, deserializes it).
jaroslav@1890
  1406
     * @param s the stream
jaroslav@1890
  1407
     */
jaroslav@1890
  1408
    private void readObject(java.io.ObjectInputStream s)
jaroslav@1890
  1409
        throws java.io.IOException, ClassNotFoundException {
jaroslav@1890
  1410
        s.defaultReadObject();
jaroslav@1890
  1411
jaroslav@1890
  1412
        // Read in elements until trailing null sentinel found
jaroslav@1890
  1413
        Node<E> h = null, t = null;
jaroslav@1890
  1414
        Object item;
jaroslav@1890
  1415
        while ((item = s.readObject()) != null) {
jaroslav@1890
  1416
            @SuppressWarnings("unchecked")
jaroslav@1890
  1417
            Node<E> newNode = new Node<E>((E) item);
jaroslav@1890
  1418
            if (h == null)
jaroslav@1890
  1419
                h = t = newNode;
jaroslav@1890
  1420
            else {
jaroslav@1890
  1421
                t.lazySetNext(newNode);
jaroslav@1890
  1422
                newNode.lazySetPrev(t);
jaroslav@1890
  1423
                t = newNode;
jaroslav@1890
  1424
            }
jaroslav@1890
  1425
        }
jaroslav@1890
  1426
        initHeadTail(h, t);
jaroslav@1890
  1427
    }
jaroslav@1890
  1428
jaroslav@1890
  1429
jaroslav@1890
  1430
    private boolean casHead(Node<E> cmp, Node<E> val) {
jaroslav@1895
  1431
        if (head == cmp) {
jaroslav@1895
  1432
            head = val;
jaroslav@1895
  1433
            return true;
jaroslav@1895
  1434
        }
jaroslav@1895
  1435
        return false;
jaroslav@1890
  1436
    }
jaroslav@1890
  1437
jaroslav@1890
  1438
    private boolean casTail(Node<E> cmp, Node<E> val) {
jaroslav@1895
  1439
        if (tail == cmp) {
jaroslav@1895
  1440
            tail = val;
jaroslav@1895
  1441
            return true;
jaroslav@1895
  1442
        }
jaroslav@1895
  1443
        return false;
jaroslav@1890
  1444
    }
jaroslav@1890
  1445
jaroslav@1890
  1446
    static {
jaroslav@1890
  1447
        PREV_TERMINATOR = new Node<Object>();
jaroslav@1890
  1448
        PREV_TERMINATOR.next = PREV_TERMINATOR;
jaroslav@1890
  1449
        NEXT_TERMINATOR = new Node<Object>();
jaroslav@1890
  1450
        NEXT_TERMINATOR.prev = NEXT_TERMINATOR;
jaroslav@1890
  1451
    }
jaroslav@1890
  1452
}