16232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson/* 26232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Written by Doug Lea and Martin Buchholz with assistance from members of 36232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * JCP JSR-166 Expert Group and released to the public domain, as explained 4a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * at http://creativecommons.org/publicdomain/zero/1.0/ 56232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 66232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 76232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilsonpackage java.util.concurrent; 86232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 96232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilsonimport java.util.AbstractCollection; 10e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniakimport java.util.Arrays; 116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilsonimport java.util.Collection; 126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilsonimport java.util.Deque; 136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilsonimport java.util.Iterator; 146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilsonimport java.util.NoSuchElementException; 15e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniakimport java.util.Objects; 168eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilsonimport java.util.Queue; 17e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniakimport java.util.Spliterator; 18e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniakimport java.util.Spliterators; 19e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniakimport java.util.function.Consumer; 208eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson 218eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson// BEGIN android-note 228eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson// removed link to collections framework docs 238eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson// END android-note 246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson/** 268eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * An unbounded concurrent {@linkplain Deque deque} based on linked nodes. 278eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * Concurrent insertion, removal, and access operations execute safely 288eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * across multiple threads. 298eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * A {@code ConcurrentLinkedDeque} is an appropriate choice when 308eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * many threads will share access to a common collection. 318eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * Like most other concurrent collection implementations, this class 328eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * does not permit the use of {@code null} elements. 338eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * 34e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * <p>Iterators and spliterators are 35e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. 366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 37a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * <p>Beware that, unlike in most collections, the {@code size} method 38a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * is <em>NOT</em> a constant-time operation. Because of the 396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * asynchronous nature of these deques, determining the current number 40a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * of elements requires a traversal of the elements, and so may report 41a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * inaccurate results if this collection is modified during traversal. 42a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * Additionally, the bulk operations {@code addAll}, 43a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * {@code removeAll}, {@code retainAll}, {@code containsAll}, 44a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * {@code equals}, and {@code toArray} are <em>not</em> guaranteed 45a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * to be performed atomically. For example, an iterator operating 46a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * concurrently with an {@code addAll} operation might view only some 47a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * of the added elements. 486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 498eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * <p>This class and its iterator implement all of the <em>optional</em> 508eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * methods of the {@link Deque} and {@link Iterator} interfaces. 518eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * 528eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * <p>Memory consistency effects: As with other concurrent collections, 538eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * actions in a thread prior to placing an object into a 548eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * {@code ConcurrentLinkedDeque} 558eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> 568eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * actions subsequent to the access or removal of that element from 578eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * the {@code ConcurrentLinkedDeque} in another thread. 586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 598eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * @since 1.7 608eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * @author Doug Lea 618eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * @author Martin Buchholz 62e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @param <E> the type of elements held in this deque 636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilsonpublic class ConcurrentLinkedDeque<E> 656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson extends AbstractCollection<E> 666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson implements Deque<E>, java.io.Serializable { 676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /* 696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * This is an implementation of a concurrent lock-free deque 706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * supporting interior removes but not interior insertions, as 718eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * required to support the entire Deque interface. 728eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * 738eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * We extend the techniques developed for ConcurrentLinkedQueue and 748eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * LinkedTransferQueue (see the internal docs for those classes). 758eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * Understanding the ConcurrentLinkedQueue implementation is a 768eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * prerequisite for understanding the implementation of this class. 778eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * 788eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * The data structure is a symmetrical doubly-linked "GC-robust" 798eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * linked list of nodes. We minimize the number of volatile writes 808eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * using two techniques: advancing multiple hops with a single CAS 818eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * and mixing volatile and non-volatile writes of the same memory 828eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * locations. 838eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * 848eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * A node contains the expected E ("item") and links to predecessor 858eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * ("prev") and successor ("next") nodes: 868eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * 878eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * class Node<E> { volatile Node<E> prev, next; volatile E item; } 886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 898eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * A node p is considered "live" if it contains a non-null item 908eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * (p.item != null). When an item is CASed to null, the item is 918eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * atomically logically deleted from the collection. 926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 938eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * At any time, there is precisely one "first" node with a null 948eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * prev reference that terminates any chain of prev references 958eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * starting at a live node. Similarly there is precisely one 968eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * "last" node terminating any chain of next references starting at 978eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * a live node. The "first" and "last" nodes may or may not be live. 988eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * The "first" and "last" nodes are always mutually reachable. 996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 1008eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * A new element is added atomically by CASing the null prev or 1018eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * next reference in the first or last node to a fresh node 1028eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * containing the element. The element's node atomically becomes 1038eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * "live" at that point. 1048eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * 1058eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * A node is considered "active" if it is a live node, or the 1068eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * first or last node. Active nodes cannot be unlinked. 1078eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * 1088eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * A "self-link" is a next or prev reference that is the same node: 1098eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * p.prev == p or p.next == p 1108eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * Self-links are used in the node unlinking process. Active nodes 1118eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * never have self-links. 1128eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * 1138eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * A node p is active if and only if: 1146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 1156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * p.item != null || 1166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * (p.prev == null && p.next != p) || 1176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * (p.next == null && p.prev != p) 1186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 1198eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * The deque object has two node references, "head" and "tail". 1208eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * The head and tail are only approximations to the first and last 1218eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * nodes of the deque. The first node can always be found by 1226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * following prev pointers from head; likewise for tail. However, 1238eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * it is permissible for head and tail to be referring to deleted 1248eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * nodes that have been unlinked and so may not be reachable from 1258eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * any live node. 1268eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * 1278eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * There are 3 stages of node deletion; 1288eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * "logical deletion", "unlinking", and "gc-unlinking". 1298eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * 1308eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * 1. "logical deletion" by CASing item to null atomically removes 1318eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * the element from the collection, and makes the containing node 1328eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * eligible for unlinking. 1336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 1348eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * 2. "unlinking" makes a deleted node unreachable from active 1358eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * nodes, and thus eventually reclaimable by GC. Unlinked nodes 1368eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * may remain reachable indefinitely from an iterator. 1376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 1388eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * Physical node unlinking is merely an optimization (albeit a 1398eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * critical one), and so can be performed at our convenience. At 1408eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * any time, the set of live nodes maintained by prev and next 1418eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * links are identical, that is, the live nodes found via next 1428eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * links from the first node is equal to the elements found via 1438eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * prev links from the last node. However, this is not true for 1448eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * nodes that have already been logically deleted - such nodes may 1458eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * be reachable in one direction only. 1466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 1478eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * 3. "gc-unlinking" takes unlinking further by making active 1488eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * nodes unreachable from deleted nodes, making it easier for the 1498eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * GC to reclaim future deleted nodes. This step makes the data 1508eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * structure "gc-robust", as first described in detail by Boehm 1518eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * (http://portal.acm.org/citation.cfm?doid=503272.503282). 1526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 1538eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * GC-unlinked nodes may remain reachable indefinitely from an 1548eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * iterator, but unlike unlinked nodes, are never reachable from 1558eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * head or tail. 1568eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * 1578eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * Making the data structure GC-robust will eliminate the risk of 1588eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * unbounded memory retention with conservative GCs and is likely 1598eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * to improve performance with generational GCs. 1608eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * 1618eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * When a node is dequeued at either end, e.g. via poll(), we would 1628eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * like to break any references from the node to active nodes. We 1638eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * develop further the use of self-links that was very effective in 1648eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * other concurrent collection classes. The idea is to replace 1658eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * prev and next pointers with special values that are interpreted 1668eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * to mean off-the-list-at-one-end. These are approximations, but 1678eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * good enough to preserve the properties we want in our 1688eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * traversals, e.g. we guarantee that a traversal will never visit 1698eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * the same element twice, but we don't guarantee whether a 1708eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * traversal that runs out of elements will be able to see more 1718eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * elements later after enqueues at that end. Doing gc-unlinking 1728eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * safely is particularly tricky, since any node can be in use 1738eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * indefinitely (for example by an iterator). We must ensure that 1748eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * the nodes pointed at by head/tail never get gc-unlinked, since 1758eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * head/tail are needed to get "back on track" by other nodes that 1768eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * are gc-unlinked. gc-unlinking accounts for much of the 1778eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * implementation complexity. 1786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 1796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Since neither unlinking nor gc-unlinking are necessary for 1806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * correctness, there are many implementation choices regarding 1816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * frequency (eagerness) of these operations. Since volatile 1826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * reads are likely to be much cheaper than CASes, saving CASes by 1836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * unlinking multiple adjacent nodes at a time may be a win. 1846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * gc-unlinking can be performed rarely and still be effective, 1856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * since it is most important that long chains of deleted nodes 1866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * are occasionally broken. 1876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 1886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * The actual representation we use is that p.next == p means to 1898eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * goto the first node (which in turn is reached by following prev 1908eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * pointers from head), and p.next == null && p.prev == p means 1918eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * that the iteration is at an end and that p is a (static final) 1926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * dummy node, NEXT_TERMINATOR, and not the last active node. 1936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Finishing the iteration when encountering such a TERMINATOR is 1948eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * good enough for read-only traversals, so such traversals can use 1958eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * p.next == null as the termination condition. When we need to 1968eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * find the last (active) node, for enqueueing a new node, we need 1978eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * to check whether we have reached a TERMINATOR node; if so, 1988eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * restart traversal from tail. 1996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 2006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * The implementation is completely directionally symmetrical, 2016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * except that most public methods that iterate through the list 2026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * follow next pointers ("forward" direction). 2036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 2048eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * We believe (without full proof) that all single-element deque 2058eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * operations (e.g., addFirst, peekLast, pollLast) are linearizable 2068eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * (see Herlihy and Shavit's book). However, some combinations of 2078eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * operations are known not to be linearizable. In particular, 2088eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * when an addFirst(A) is racing with pollFirst() removing B, it is 2098eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * possible for an observer iterating over the elements to observe 2108eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * A B C and subsequently observe A C, even though no interior 2118eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * removes are ever performed. Nevertheless, iterators behave 2128eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * reasonably, providing the "weakly consistent" guarantees. 2136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 2146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Empirically, microbenchmarks suggest that this class adds about 2156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 40% overhead relative to ConcurrentLinkedQueue, which feels as 2166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * good as we can hope for. 2176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 2186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 2198eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson private static final long serialVersionUID = 876323262645176354L; 2208eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson 2216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 2228eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * A node from which the first node on list (that is, the unique node p 2238eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * with p.prev == null && p.next != p) can be reached in O(1) time. 2246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Invariants: 2256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * - the first node is always O(1) reachable from head via prev links 2266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * - all live nodes are reachable from the first node via succ() 2276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * - head != null 2286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * - (tmp = head).next != tmp || tmp != head 2298eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * - head is never gc-unlinked (but may be unlinked) 2306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Non-invariants: 2316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * - head.item may or may not be null 2326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * - head may not be reachable from the first or last node, or from tail 2336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 2348eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson private transient volatile Node<E> head; 2356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 2368eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson /** 2378eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * A node from which the last node on list (that is, the unique node p 2388eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * with p.next == null && p.prev != p) can be reached in O(1) time. 2398eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * Invariants: 2408eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * - the last node is always O(1) reachable from tail via next links 2418eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * - all live nodes are reachable from the last node via pred() 2428eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * - tail != null 2438eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * - tail is never gc-unlinked (but may be unlinked) 2448eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * Non-invariants: 2458eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * - tail.item may or may not be null 2468eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * - tail may not be reachable from the first or last node, or from head 2478eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson */ 2488eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson private transient volatile Node<E> tail; 2498eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson 2508eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson private static final Node<Object> PREV_TERMINATOR, NEXT_TERMINATOR; 2516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 2526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson @SuppressWarnings("unchecked") 2536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node<E> prevTerminator() { 2546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return (Node<E>) PREV_TERMINATOR; 2556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 2566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 2576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson @SuppressWarnings("unchecked") 2586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node<E> nextTerminator() { 2596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return (Node<E>) NEXT_TERMINATOR; 2606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 2616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 2626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson static final class Node<E> { 2636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson volatile Node<E> prev; 2646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson volatile E item; 2656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson volatile Node<E> next; 2666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 267a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson Node() { // default constructor for NEXT_TERMINATOR, PREV_TERMINATOR 268a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 269a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 2708eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson /** 2718eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * Constructs a new node. Uses relaxed write because item can 2728eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * only be seen after publication via casNext or casPrev. 2738eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson */ 2746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node(E item) { 275e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak U.putObject(this, ITEM, item); 2766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 2776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 2786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson boolean casItem(E cmp, E val) { 279e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return U.compareAndSwapObject(this, ITEM, cmp, val); 2806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 2816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 2826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson void lazySetNext(Node<E> val) { 283e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak U.putOrderedObject(this, NEXT, val); 2846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 2856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 2866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson boolean casNext(Node<E> cmp, Node<E> val) { 287e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return U.compareAndSwapObject(this, NEXT, cmp, val); 2886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 2896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 2906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson void lazySetPrev(Node<E> val) { 291e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak U.putOrderedObject(this, PREV, val); 2926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 2936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 2946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson boolean casPrev(Node<E> cmp, Node<E> val) { 295e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return U.compareAndSwapObject(this, PREV, cmp, val); 2966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 2976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 2986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // Unsafe mechanics 2996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 300e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe(); 301e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak private static final long PREV; 302e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak private static final long ITEM; 303e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak private static final long NEXT; 304a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 305a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson static { 306a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson try { 307e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak PREV = U.objectFieldOffset 308e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak (Node.class.getDeclaredField("prev")); 309e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak ITEM = U.objectFieldOffset 310e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak (Node.class.getDeclaredField("item")); 311e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak NEXT = U.objectFieldOffset 312e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak (Node.class.getDeclaredField("next")); 313e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } catch (ReflectiveOperationException e) { 314a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson throw new Error(e); 315a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 316a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 3176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 3186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 3196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 3206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Links e as first element. 3216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 3226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private void linkFirst(E e) { 323e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak final Node<E> newNode = new Node<E>(Objects.requireNonNull(e)); 3246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 3258eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson restartFromHead: 3268eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson for (;;) 3278eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson for (Node<E> h = head, p = h, q;;) { 3288eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson if ((q = p.prev) != null && 3298eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson (q = (p = q).prev) != null) 3308eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // Check for head updates every other hop. 3318eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // If p == q, we are sure to follow head instead. 3328eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson p = (h != (h = head)) ? h : q; 3338eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson else if (p.next == p) // PREV_TERMINATOR 3348eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson continue restartFromHead; 3358eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson else { 3368eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // p is first node 3376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson newNode.lazySetNext(p); // CAS piggyback 3386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (p.casPrev(null, newNode)) { 3398eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // Successful CAS is the linearization point 3408eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // for e to become an element of this deque, 3418eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // and for newNode to become "live". 3426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (p != h) // hop two nodes at a time 3438eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson casHead(h, newNode); // Failure is OK. 3446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return; 3456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 3468eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // Lost CAS race to another thread; re-read prev 3476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 3486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 3496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 3506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 3516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 3526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Links e as last element. 3536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 3546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private void linkLast(E e) { 355e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak final Node<E> newNode = new Node<E>(Objects.requireNonNull(e)); 3566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 3578eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson restartFromTail: 3588eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson for (;;) 3598eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson for (Node<E> t = tail, p = t, q;;) { 3608eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson if ((q = p.next) != null && 3618eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson (q = (p = q).next) != null) 3628eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // Check for tail updates every other hop. 3638eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // If p == q, we are sure to follow tail instead. 3648eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson p = (t != (t = tail)) ? t : q; 3658eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson else if (p.prev == p) // NEXT_TERMINATOR 3668eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson continue restartFromTail; 3678eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson else { 3688eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // p is last node 3696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson newNode.lazySetPrev(p); // CAS piggyback 3706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (p.casNext(null, newNode)) { 3718eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // Successful CAS is the linearization point 3728eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // for e to become an element of this deque, 3738eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // and for newNode to become "live". 3746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (p != t) // hop two nodes at a time 3758eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson casTail(t, newNode); // Failure is OK. 3766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return; 3776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 3788eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // Lost CAS race to another thread; re-read next 3796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 3806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 3816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 3826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 3838eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson private static final int HOPS = 2; 3846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 3856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 3866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Unlinks non-null node x. 3876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 3886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson void unlink(Node<E> x) { 3898eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // assert x != null; 3908eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // assert x.item == null; 3918eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // assert x != PREV_TERMINATOR; 3928eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // assert x != NEXT_TERMINATOR; 3936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 3946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson final Node<E> prev = x.prev; 3956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson final Node<E> next = x.next; 3966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (prev == null) { 3976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson unlinkFirst(x, next); 3986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } else if (next == null) { 3996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson unlinkLast(x, prev); 4006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } else { 4016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // Unlink interior node. 4026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // 4036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // This is the common case, since a series of polls at the 4046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // same end will be "interior" removes, except perhaps for 4058eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // the first one, since end nodes cannot be unlinked. 4066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // 4076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // At any time, all active nodes are mutually reachable by 4086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // following a sequence of either next or prev pointers. 4096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // 4106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // Our strategy is to find the unique active predecessor 4116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // and successor of x. Try to fix up their links so that 4126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // they point to each other, leaving x unreachable from 4136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // active nodes. If successful, and if x has no live 4148eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // predecessor/successor, we additionally try to gc-unlink, 4158eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // leaving active nodes unreachable from x, by rechecking 4168eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // that the status of predecessor and successor are 4178eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // unchanged and ensuring that x is not reachable from 4188eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // tail/head, before setting x's prev/next links to their 4198eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // logical approximate replacements, self/TERMINATOR. 4206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node<E> activePred, activeSucc; 4216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson boolean isFirst, isLast; 4226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson int hops = 1; 4236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 4246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // Find active predecessor 4258eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson for (Node<E> p = prev; ; ++hops) { 4266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (p.item != null) { 4276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson activePred = p; 4286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson isFirst = false; 4296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson break; 4306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 4316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node<E> q = p.prev; 4326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (q == null) { 4338eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson if (p.next == p) 4346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return; 4356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson activePred = p; 4366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson isFirst = true; 4376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson break; 4386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 4396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson else if (p == q) 4406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return; 4416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson else 4426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson p = q; 4436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 4446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 4456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // Find active successor 4468eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson for (Node<E> p = next; ; ++hops) { 4476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (p.item != null) { 4486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson activeSucc = p; 4496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson isLast = false; 4506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson break; 4516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 4526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node<E> q = p.next; 4536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (q == null) { 4548eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson if (p.prev == p) 4556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return; 4566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson activeSucc = p; 4576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson isLast = true; 4586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson break; 4596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 4606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson else if (p == q) 4616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return; 4626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson else 4636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson p = q; 4646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 4656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 4666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // TODO: better HOP heuristics 4676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (hops < HOPS 4686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // always squeeze out interior deleted nodes 4696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson && (isFirst | isLast)) 4706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return; 4716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 4726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // Squeeze out deleted nodes between activePred and 4736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // activeSucc, including x. 4746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson skipDeletedSuccessors(activePred); 4756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson skipDeletedPredecessors(activeSucc); 4766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 4776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // Try to gc-unlink, if possible 4786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if ((isFirst | isLast) && 4796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 4806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // Recheck expected state of predecessor and successor 4816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson (activePred.next == activeSucc) && 4826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson (activeSucc.prev == activePred) && 4836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson (isFirst ? activePred.prev == null : activePred.item != null) && 4846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson (isLast ? activeSucc.next == null : activeSucc.item != null)) { 4856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 4868eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson updateHead(); // Ensure x is not reachable from head 4878eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson updateTail(); // Ensure x is not reachable from tail 4888eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson 4898eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // Finally, actually gc-unlink 4906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson x.lazySetPrev(isFirst ? prevTerminator() : x); 4916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson x.lazySetNext(isLast ? nextTerminator() : x); 4926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 4936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 4946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 4956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 4966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 4976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Unlinks non-null first node. 4986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 4996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private void unlinkFirst(Node<E> first, Node<E> next) { 5008eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // assert first != null; 5018eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // assert next != null; 5028eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // assert first.item == null; 5038eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson for (Node<E> o = null, p = next, q;;) { 5046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (p.item != null || (q = p.next) == null) { 5058eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson if (o != null && p.prev != p && first.casNext(next, p)) { 5068eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson skipDeletedPredecessors(p); 5078eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson if (first.prev == null && 5088eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson (p.next == null || p.item != null) && 5098eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson p.prev == first) { 5108eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson 5118eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson updateHead(); // Ensure o is not reachable from head 5128eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson updateTail(); // Ensure o is not reachable from tail 5138eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson 5148eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // Finally, actually gc-unlink 5158eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson o.lazySetNext(o); 5168eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson o.lazySetPrev(prevTerminator()); 5176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 5186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 5196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return; 5206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 5216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson else if (p == q) 5226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return; 5236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson else { 5246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson o = p; 5256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson p = q; 5266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 5276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 5286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 5296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 5306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 5316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Unlinks non-null last node. 5326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 5336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private void unlinkLast(Node<E> last, Node<E> prev) { 5348eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // assert last != null; 5358eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // assert prev != null; 5368eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // assert last.item == null; 5378eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson for (Node<E> o = null, p = prev, q;;) { 5386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (p.item != null || (q = p.prev) == null) { 5398eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson if (o != null && p.next != p && last.casPrev(prev, p)) { 5408eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson skipDeletedSuccessors(p); 5418eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson if (last.next == null && 5428eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson (p.prev == null || p.item != null) && 5438eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson p.next == last) { 5448eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson 5458eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson updateHead(); // Ensure o is not reachable from head 5468eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson updateTail(); // Ensure o is not reachable from tail 5478eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson 5488eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // Finally, actually gc-unlink 5498eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson o.lazySetPrev(o); 5508eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson o.lazySetNext(nextTerminator()); 5516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 5526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 5536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return; 5546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 5556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson else if (p == q) 5566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return; 5576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson else { 5586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson o = p; 5596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson p = q; 5606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 5616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 5626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 5636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 5648eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson /** 5658eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * Guarantees that any node which was unlinked before a call to 5668eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * this method will be unreachable from head after it returns. 5678eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * Does not guarantee to eliminate slack, only that head will 5688eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * point to a node that was active while this method was running. 5698eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson */ 5706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private final void updateHead() { 5718eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // Either head already points to an active node, or we keep 5728eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // trying to cas it to the first node until it does. 5738eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson Node<E> h, p, q; 5748eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson restartFromHead: 5758eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson while ((h = head).item == null && (p = h.prev) != null) { 5768eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson for (;;) { 5778eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson if ((q = p.prev) == null || 5788eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson (q = (p = q).prev) == null) { 5798eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // It is possible that p is PREV_TERMINATOR, 5808eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // but if so, the CAS is guaranteed to fail. 5818eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson if (casHead(h, p)) 5828eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson return; 5838eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson else 5848eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson continue restartFromHead; 5858eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson } 5868eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson else if (h != head) 5878eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson continue restartFromHead; 5888eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson else 5898eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson p = q; 5908eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson } 5918eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson } 5926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 5936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 5948eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson /** 5958eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * Guarantees that any node which was unlinked before a call to 5968eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * this method will be unreachable from tail after it returns. 5978eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * Does not guarantee to eliminate slack, only that tail will 5988eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * point to a node that was active while this method was running. 5998eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson */ 6006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private final void updateTail() { 6018eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // Either tail already points to an active node, or we keep 6028eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // trying to cas it to the last node until it does. 6038eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson Node<E> t, p, q; 6048eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson restartFromTail: 6058eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson while ((t = tail).item == null && (p = t.next) != null) { 6068eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson for (;;) { 6078eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson if ((q = p.next) == null || 6088eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson (q = (p = q).next) == null) { 6098eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // It is possible that p is NEXT_TERMINATOR, 6108eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // but if so, the CAS is guaranteed to fail. 6118eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson if (casTail(t, p)) 6128eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson return; 6138eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson else 6148eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson continue restartFromTail; 6158eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson } 6168eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson else if (t != tail) 6178eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson continue restartFromTail; 6188eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson else 6198eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson p = q; 6208eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson } 6218eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson } 6226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 6236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 6246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private void skipDeletedPredecessors(Node<E> x) { 6256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson whileActive: 6266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson do { 6276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node<E> prev = x.prev; 6288eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // assert prev != null; 6298eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // assert x != NEXT_TERMINATOR; 6308eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // assert x != PREV_TERMINATOR; 6316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node<E> p = prev; 6326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson findActive: 6336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (;;) { 6346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (p.item != null) 6356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson break findActive; 6366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node<E> q = p.prev; 6376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (q == null) { 6386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (p.next == p) 6396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson continue whileActive; 6406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson break findActive; 6416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 6426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson else if (p == q) 6436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson continue whileActive; 6446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson else 6456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson p = q; 6466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 6476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 6486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // found active CAS target 6496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (prev == p || x.casPrev(prev, p)) 6506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return; 6516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 6526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } while (x.item != null || x.next == null); 6536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 6546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 6556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private void skipDeletedSuccessors(Node<E> x) { 6566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson whileActive: 6576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson do { 6586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node<E> next = x.next; 6598eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // assert next != null; 6608eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // assert x != NEXT_TERMINATOR; 6618eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // assert x != PREV_TERMINATOR; 6626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node<E> p = next; 6636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson findActive: 6646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (;;) { 6656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (p.item != null) 6666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson break findActive; 6676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node<E> q = p.next; 6686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (q == null) { 6696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (p.prev == p) 6706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson continue whileActive; 6716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson break findActive; 6726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 6736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson else if (p == q) 6746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson continue whileActive; 6756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson else 6766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson p = q; 6776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 6786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 6796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // found active CAS target 6806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (next == p || x.casNext(next, p)) 6816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return; 6826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 6836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } while (x.item != null || x.prev == null); 6846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 6856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 6866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 6876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns the successor of p, or the first node if p.next has been 6886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * linked to self, which will only be true if traversing with a 6896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * stale pointer that is now off the list. 6906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 6916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson final Node<E> succ(Node<E> p) { 6926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // TODO: should we skip deleted nodes here? 6936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node<E> q = p.next; 6946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return (p == q) ? first() : q; 6956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 6966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 6976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 6986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns the predecessor of p, or the last node if p.prev has been 6996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * linked to self, which will only be true if traversing with a 7006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * stale pointer that is now off the list. 7016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 7026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson final Node<E> pred(Node<E> p) { 7036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node<E> q = p.prev; 7046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return (p == q) ? last() : q; 7056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 7066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 7076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 7088eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * Returns the first node, the unique node p for which: 7098eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * p.prev == null && p.next != p 7106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * The returned node may or may not be logically deleted. 7116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Guarantees that head is set to the returned node. 7126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 7136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node<E> first() { 7148eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson restartFromHead: 7158eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson for (;;) 7168eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson for (Node<E> h = head, p = h, q;;) { 7178eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson if ((q = p.prev) != null && 7188eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson (q = (p = q).prev) != null) 7198eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // Check for head updates every other hop. 7208eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // If p == q, we are sure to follow head instead. 7218eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson p = (h != (h = head)) ? h : q; 7228eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson else if (p == h 7238eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // It is possible that p is PREV_TERMINATOR, 7248eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // but if so, the CAS is guaranteed to fail. 7258eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson || casHead(h, p)) 7268eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson return p; 7278eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson else 7288eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson continue restartFromHead; 7296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 7306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 7316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 7326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 7338eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * Returns the last node, the unique node p for which: 7348eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * p.next == null && p.prev != p 7356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * The returned node may or may not be logically deleted. 7366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Guarantees that tail is set to the returned node. 7376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 7386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node<E> last() { 7398eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson restartFromTail: 7408eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson for (;;) 7418eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson for (Node<E> t = tail, p = t, q;;) { 7428eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson if ((q = p.next) != null && 7438eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson (q = (p = q).next) != null) 7448eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // Check for tail updates every other hop. 7458eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // If p == q, we are sure to follow tail instead. 7468eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson p = (t != (t = tail)) ? t : q; 7478eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson else if (p == t 7488eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // It is possible that p is NEXT_TERMINATOR, 7498eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // but if so, the CAS is guaranteed to fail. 7508eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson || casTail(t, p)) 7518eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson return p; 7528eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson else 7538eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson continue restartFromTail; 7546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 7556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 7566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 7576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // Minor convenience utilities 7586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 7596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 7606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns element unless it is null, in which case throws 7616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * NoSuchElementException. 7626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 7636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param v the element 7646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return the element 7656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 7666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private E screenNullResult(E v) { 7676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (v == null) 7686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new NoSuchElementException(); 7696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return v; 7706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 7716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 7726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 7736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Constructs an empty deque. 7746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 7758eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson public ConcurrentLinkedDeque() { 7768eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson head = tail = new Node<E>(null); 7778eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson } 7786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 7796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 7806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Constructs a deque initially containing the elements of 7816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * the given collection, added in traversal order of the 7826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * collection's iterator. 7836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 7846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param c the collection of elements to initially contain 7856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws NullPointerException if the specified collection or any 7866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * of its elements are null 7876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 7888eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson public ConcurrentLinkedDeque(Collection<? extends E> c) { 7898eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // Copy c into a private chain of Nodes 7908eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson Node<E> h = null, t = null; 7918eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson for (E e : c) { 792e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak Node<E> newNode = new Node<E>(Objects.requireNonNull(e)); 7938eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson if (h == null) 7948eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson h = t = newNode; 7958eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson else { 7968eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson t.lazySetNext(newNode); 7978eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson newNode.lazySetPrev(t); 7988eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson t = newNode; 7998eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson } 8008eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson } 8018eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson initHeadTail(h, t); 8028eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson } 8038eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson 8048eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson /** 8058eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * Initializes head and tail, ensuring invariants hold. 8068eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson */ 8078eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson private void initHeadTail(Node<E> h, Node<E> t) { 8088eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson if (h == t) { 8098eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson if (h == null) 8108eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson h = t = new Node<E>(null); 8118eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson else { 8128eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // Avoid edge case of a single Node with non-null item. 8138eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson Node<E> newNode = new Node<E>(null); 8148eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson t.lazySetNext(newNode); 8158eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson newNode.lazySetPrev(t); 8168eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson t = newNode; 8178eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson } 8188eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson } 8198eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson head = h; 8208eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson tail = t; 8218eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson } 8226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 8236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 8246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Inserts the specified element at the front of this deque. 8258eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * As the deque is unbounded, this method will never throw 8268eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * {@link IllegalStateException}. 8276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 8288eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * @throws NullPointerException if the specified element is null 8296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 8306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public void addFirst(E e) { 8316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson linkFirst(e); 8326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 8336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 8346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 8356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Inserts the specified element at the end of this deque. 8368eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * As the deque is unbounded, this method will never throw 8378eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * {@link IllegalStateException}. 8386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 8398eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * <p>This method is equivalent to {@link #add}. 8408eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * 8418eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * @throws NullPointerException if the specified element is null 8426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 8436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public void addLast(E e) { 8446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson linkLast(e); 8456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 8466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 8476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 8486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Inserts the specified element at the front of this deque. 8498eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * As the deque is unbounded, this method will never return {@code false}. 8506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 8518eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * @return {@code true} (as specified by {@link Deque#offerFirst}) 8528eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * @throws NullPointerException if the specified element is null 8536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 8546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public boolean offerFirst(E e) { 8556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson linkFirst(e); 8566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return true; 8576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 8586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 8596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 8606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Inserts the specified element at the end of this deque. 8618eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * As the deque is unbounded, this method will never return {@code false}. 8626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 8636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>This method is equivalent to {@link #add}. 8646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 8658eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * @return {@code true} (as specified by {@link Deque#offerLast}) 8668eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * @throws NullPointerException if the specified element is null 8676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 8686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public boolean offerLast(E e) { 8696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson linkLast(e); 8706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return true; 8716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 8726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 8736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public E peekFirst() { 8746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (Node<E> p = first(); p != null; p = succ(p)) { 8756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson E item = p.item; 8766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (item != null) 8776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return item; 8786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 8796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return null; 8806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 8816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 8826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public E peekLast() { 8836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (Node<E> p = last(); p != null; p = pred(p)) { 8846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson E item = p.item; 8856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (item != null) 8866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return item; 8876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 8886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return null; 8896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 8906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 8916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 8926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws NoSuchElementException {@inheritDoc} 8936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 8946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public E getFirst() { 8956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return screenNullResult(peekFirst()); 8966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 8976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 8986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 8996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws NoSuchElementException {@inheritDoc} 9006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 9018eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson public E getLast() { 9026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return screenNullResult(peekLast()); 9036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 9046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 9056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public E pollFirst() { 9066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (Node<E> p = first(); p != null; p = succ(p)) { 9076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson E item = p.item; 9086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (item != null && p.casItem(item, null)) { 9096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson unlink(p); 9106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return item; 9116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 9126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 9136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return null; 9146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 9156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 9166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public E pollLast() { 9176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (Node<E> p = last(); p != null; p = pred(p)) { 9186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson E item = p.item; 9196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (item != null && p.casItem(item, null)) { 9206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson unlink(p); 9216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return item; 9226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 9236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 9246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return null; 9256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 9266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 9276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 9286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws NoSuchElementException {@inheritDoc} 9296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 9306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public E removeFirst() { 9316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return screenNullResult(pollFirst()); 9326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 9336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 9346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 9356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws NoSuchElementException {@inheritDoc} 9366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 9376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public E removeLast() { 9386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return screenNullResult(pollLast()); 9396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 9406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 9416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // *** Queue and stack methods *** 9426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 9436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 9446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Inserts the specified element at the tail of this deque. 9458eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * As the deque is unbounded, this method will never return {@code false}. 9466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 9478eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * @return {@code true} (as specified by {@link Queue#offer}) 9486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws NullPointerException if the specified element is null 9496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 9506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public boolean offer(E e) { 9516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return offerLast(e); 9526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 9536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 9546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 9556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Inserts the specified element at the tail of this deque. 9568eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * As the deque is unbounded, this method will never throw 9578eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * {@link IllegalStateException} or return {@code false}. 9586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 9596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return {@code true} (as specified by {@link Collection#add}) 9606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws NullPointerException if the specified element is null 9616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 9626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public boolean add(E e) { 9636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return offerLast(e); 9646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 9656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 9666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public E poll() { return pollFirst(); } 9676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public E peek() { return peekFirst(); } 968e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak 969e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak /** 970e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @throws NoSuchElementException {@inheritDoc} 971e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak */ 972e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak public E remove() { return removeFirst(); } 973e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak 974e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak /** 975e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @throws NoSuchElementException {@inheritDoc} 976e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak */ 977e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak public E pop() { return removeFirst(); } 978e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak 979e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak /** 980e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @throws NoSuchElementException {@inheritDoc} 981e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak */ 9826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public E element() { return getFirst(); } 983e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak 984e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak /** 985e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @throws NullPointerException {@inheritDoc} 986e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak */ 9876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public void push(E e) { addFirst(e); } 9886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 9896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 990e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * Removes the first occurrence of the specified element from this deque. 9916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * If the deque does not contain the element, it is unchanged. 992e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * More formally, removes the first element {@code e} such that 993e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * {@code o.equals(e)} (if such an element exists). 994e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * Returns {@code true} if this deque contained the specified element 995e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * (or equivalently, if this deque changed as a result of the call). 9966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 9976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param o element to be removed from this deque, if present 9986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return {@code true} if the deque contained the specified element 9998eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * @throws NullPointerException if the specified element is null 10006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 10016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public boolean removeFirstOccurrence(Object o) { 1002e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak Objects.requireNonNull(o); 10036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (Node<E> p = first(); p != null; p = succ(p)) { 10046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson E item = p.item; 10056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (item != null && o.equals(item) && p.casItem(item, null)) { 10066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson unlink(p); 10076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return true; 10086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 10096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 10106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return false; 10116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 10126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 10136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 1014e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * Removes the last occurrence of the specified element from this deque. 10156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * If the deque does not contain the element, it is unchanged. 1016e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * More formally, removes the last element {@code e} such that 1017e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * {@code o.equals(e)} (if such an element exists). 1018e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * Returns {@code true} if this deque contained the specified element 1019e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * (or equivalently, if this deque changed as a result of the call). 10206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 10216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param o element to be removed from this deque, if present 10226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return {@code true} if the deque contained the specified element 10238eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * @throws NullPointerException if the specified element is null 10246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 10256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public boolean removeLastOccurrence(Object o) { 1026e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak Objects.requireNonNull(o); 10276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (Node<E> p = last(); p != null; p = pred(p)) { 10286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson E item = p.item; 10296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (item != null && o.equals(item) && p.casItem(item, null)) { 10306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson unlink(p); 10316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return true; 10326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 10336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 10346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return false; 10356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 10366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 10376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 1038e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * Returns {@code true} if this deque contains the specified element. 1039e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * More formally, returns {@code true} if and only if this deque contains 1040e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * at least one element {@code e} such that {@code o.equals(e)}. 10416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 10426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param o element whose presence in this deque is to be tested 10436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return {@code true} if this deque contains the specified element 10446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 10456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public boolean contains(Object o) { 1046e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (o != null) { 1047e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak for (Node<E> p = first(); p != null; p = succ(p)) { 1048e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak E item = p.item; 1049e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (item != null && o.equals(item)) 1050e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return true; 1051e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 10526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 10536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return false; 10546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 10556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 10566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 10576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns {@code true} if this collection contains no elements. 10586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 10596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return {@code true} if this collection contains no elements 10606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 10616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public boolean isEmpty() { 10626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return peekFirst() == null; 10636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 10646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 10656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 10666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns the number of elements in this deque. If this deque 10676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * contains more than {@code Integer.MAX_VALUE} elements, it 10686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * returns {@code Integer.MAX_VALUE}. 10696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 10706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>Beware that, unlike in most collections, this method is 10716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <em>NOT</em> a constant-time operation. Because of the 10726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * asynchronous nature of these deques, determining the current 10736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * number of elements requires traversing them all to count them. 10746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Additionally, it is possible for the size to change during 10756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * execution of this method, in which case the returned result 10766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * will be inaccurate. Thus, this method is typically not very 10776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * useful in concurrent applications. 10786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 10796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return the number of elements in this deque 10806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 10816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public int size() { 1082e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak restartFromHead: for (;;) { 1083e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak int count = 0; 1084e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak for (Node<E> p = first(); p != null;) { 1085e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (p.item != null) 1086e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (++count == Integer.MAX_VALUE) 1087e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak break; // @see Collection.size() 1088e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (p == (p = p.next)) 1089e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak continue restartFromHead; 1090e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 1091e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return count; 1092e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 10936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 10946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 10956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 1096e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * Removes the first occurrence of the specified element from this deque. 10976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * If the deque does not contain the element, it is unchanged. 1098e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * More formally, removes the first element {@code e} such that 1099e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * {@code o.equals(e)} (if such an element exists). 1100e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * Returns {@code true} if this deque contained the specified element 1101e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * (or equivalently, if this deque changed as a result of the call). 1102e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * 1103e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * <p>This method is equivalent to {@link #removeFirstOccurrence(Object)}. 11046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 11056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param o element to be removed from this deque, if present 11066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return {@code true} if the deque contained the specified element 11078eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * @throws NullPointerException if the specified element is null 11086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 11096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public boolean remove(Object o) { 11106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return removeFirstOccurrence(o); 11116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 11126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 11136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 11146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Appends all of the elements in the specified collection to the end of 11156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * this deque, in the order that they are returned by the specified 11168eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * collection's iterator. Attempts to {@code addAll} of a deque to 11178eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * itself result in {@code IllegalArgumentException}. 11186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 11196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param c the elements to be inserted into this deque 11206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return {@code true} if this deque changed as a result of the call 11218eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * @throws NullPointerException if the specified collection or any 11228eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * of its elements are null 11238eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * @throws IllegalArgumentException if the collection is this deque 11246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 11256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public boolean addAll(Collection<? extends E> c) { 11268eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson if (c == this) 11278eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // As historically specified in AbstractQueue#addAll 11288eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson throw new IllegalArgumentException(); 11298eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson 11308eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // Copy c into a private chain of Nodes 11318eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson Node<E> beginningOfTheEnd = null, last = null; 11328eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson for (E e : c) { 1133e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak Node<E> newNode = new Node<E>(Objects.requireNonNull(e)); 11348eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson if (beginningOfTheEnd == null) 11358eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson beginningOfTheEnd = last = newNode; 11368eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson else { 11378eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson last.lazySetNext(newNode); 11388eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson newNode.lazySetPrev(last); 11398eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson last = newNode; 11408eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson } 11418eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson } 11428eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson if (beginningOfTheEnd == null) 11436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return false; 11448eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson 11458eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // Atomically append the chain at the tail of this collection 11468eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson restartFromTail: 11478eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson for (;;) 11488eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson for (Node<E> t = tail, p = t, q;;) { 11498eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson if ((q = p.next) != null && 11508eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson (q = (p = q).next) != null) 11518eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // Check for tail updates every other hop. 11528eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // If p == q, we are sure to follow tail instead. 11538eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson p = (t != (t = tail)) ? t : q; 11548eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson else if (p.prev == p) // NEXT_TERMINATOR 11558eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson continue restartFromTail; 11568eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson else { 11578eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // p is last node 11588eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson beginningOfTheEnd.lazySetPrev(p); // CAS piggyback 11598eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson if (p.casNext(null, beginningOfTheEnd)) { 11608eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // Successful CAS is the linearization point 11618eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // for all elements to be added to this deque. 11628eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson if (!casTail(t, last)) { 11638eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // Try a little harder to update tail, 11648eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // since we may be adding many elements. 11658eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson t = tail; 11668eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson if (last.next == null) 11678eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson casTail(t, last); 11688eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson } 11698eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson return true; 11708eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson } 11718eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // Lost CAS race to another thread; re-read next 11728eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson } 11738eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson } 11746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 11756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 11766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 11776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Removes all of the elements from this deque. 11786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 11796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public void clear() { 11806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson while (pollFirst() != null) 11816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson ; 11826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 11836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 1184e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak public String toString() { 1185e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak String[] a = null; 1186e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak restartFromHead: for (;;) { 1187e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak int charLength = 0; 1188e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak int size = 0; 1189e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak for (Node<E> p = first(); p != null;) { 1190e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak E item = p.item; 1191e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (item != null) { 1192e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (a == null) 1193e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak a = new String[4]; 1194e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak else if (size == a.length) 1195e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak a = Arrays.copyOf(a, 2 * size); 1196e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak String s = item.toString(); 1197e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak a[size++] = s; 1198e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak charLength += s.length(); 1199e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 1200e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (p == (p = p.next)) 1201e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak continue restartFromHead; 1202e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 1203e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak 1204e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (size == 0) 1205e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return "[]"; 1206e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak 1207e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return Helpers.toString(a, size, charLength); 1208e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 1209e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 1210e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak 1211e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak private Object[] toArrayInternal(Object[] a) { 1212e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak Object[] x = a; 1213e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak restartFromHead: for (;;) { 1214e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak int size = 0; 1215e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak for (Node<E> p = first(); p != null;) { 1216e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak E item = p.item; 1217e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (item != null) { 1218e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (x == null) 1219e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak x = new Object[4]; 1220e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak else if (size == x.length) 1221e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak x = Arrays.copyOf(x, 2 * (size + 4)); 1222e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak x[size++] = item; 1223e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 1224e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (p == (p = p.next)) 1225e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak continue restartFromHead; 1226e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 1227e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (x == null) 1228e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return new Object[0]; 1229e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak else if (a != null && size <= a.length) { 1230e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (a != x) 1231e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak System.arraycopy(x, 0, a, 0, size); 1232e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (size < a.length) 1233e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak a[size] = null; 1234e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return a; 1235e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 1236e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return (size == x.length) ? x : Arrays.copyOf(x, size); 1237e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 1238e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 1239e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak 12406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 12416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns an array containing all of the elements in this deque, in 12426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * proper sequence (from first to last element). 12436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 12446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>The returned array will be "safe" in that no references to it are 12456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * maintained by this deque. (In other words, this method must allocate 12466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * a new array). The caller is thus free to modify the returned array. 12476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 12486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>This method acts as bridge between array-based and collection-based 12496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * APIs. 12506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 12516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return an array containing all of the elements in this deque 12526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 12536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public Object[] toArray() { 1254e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return toArrayInternal(null); 12556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 12566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 12576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 12586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns an array containing all of the elements in this deque, 12596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * in proper sequence (from first to last element); the runtime 12606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * type of the returned array is that of the specified array. If 12616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * the deque fits in the specified array, it is returned therein. 12626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Otherwise, a new array is allocated with the runtime type of 12636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * the specified array and the size of this deque. 12646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 12656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>If this deque fits in the specified array with room to spare 12666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * (i.e., the array has more elements than this deque), the element in 12676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * the array immediately following the end of the deque is set to 12686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * {@code null}. 12696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 12708eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * <p>Like the {@link #toArray()} method, this method acts as 12718eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * bridge between array-based and collection-based APIs. Further, 12728eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * this method allows precise control over the runtime type of the 12738eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * output array, and may, under certain circumstances, be used to 12748eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * save allocation costs. 12756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 12766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>Suppose {@code x} is a deque known to contain only strings. 12776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * The following code can be used to dump the deque into a newly 12786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * allocated array of {@code String}: 12796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 1280e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * <pre> {@code String[] y = x.toArray(new String[0]);}</pre> 12816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 12826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Note that {@code toArray(new Object[0])} is identical in function to 12836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * {@code toArray()}. 12846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 12856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param a the array into which the elements of the deque are to 12866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * be stored, if it is big enough; otherwise, a new array of the 12876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * same runtime type is allocated for this purpose 12886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return an array containing all of the elements in this deque 12896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws ArrayStoreException if the runtime type of the specified array 12906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * is not a supertype of the runtime type of every element in 12916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * this deque 12926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws NullPointerException if the specified array is null 12936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 1294e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak @SuppressWarnings("unchecked") 12956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public <T> T[] toArray(T[] a) { 1296e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (a == null) throw new NullPointerException(); 1297e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return (T[]) toArrayInternal(a); 12986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 12996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 13006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 13016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns an iterator over the elements in this deque in proper sequence. 13026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * The elements will be returned in order from first (head) to last (tail). 13036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 1304e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * <p>The returned iterator is 1305e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. 13066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 13076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return an iterator over the elements in this deque in proper sequence 13086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 13096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public Iterator<E> iterator() { 13106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return new Itr(); 13116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 13126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 13136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 13146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns an iterator over the elements in this deque in reverse 13156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * sequential order. The elements will be returned in order from 13166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * last (tail) to first (head). 13176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 1318e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * <p>The returned iterator is 1319e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. 13208eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * 13218eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * @return an iterator over the elements in this deque in reverse order 13226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 13236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public Iterator<E> descendingIterator() { 13246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return new DescendingItr(); 13256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 13266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 13276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private abstract class AbstractItr implements Iterator<E> { 13286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 13296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Next node to return item for. 13306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 13316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private Node<E> nextNode; 13326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 13336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 13346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * nextItem holds on to item fields because once we claim 13356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * that an element exists in hasNext(), we must return it in 13366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * the following next() call even if it was in the process of 13376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * being removed when hasNext() was called. 13386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 13396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private E nextItem; 13406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 13416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 13426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Node returned by most recent call to next. Needed by remove. 13436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Reset to null if this element is deleted by a call to remove. 13446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 13456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private Node<E> lastRet; 13466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 13476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson abstract Node<E> startNode(); 13486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson abstract Node<E> nextNode(Node<E> p); 13496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 13506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson AbstractItr() { 13516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson advance(); 13526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 13536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 13546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 13556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Sets nextNode and nextItem to next valid node, or to null 13566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * if no such. 13576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 13586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private void advance() { 13596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson lastRet = nextNode; 13606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 13616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node<E> p = (nextNode == null) ? startNode() : nextNode(nextNode); 13626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (;; p = nextNode(p)) { 13636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (p == null) { 1364e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak // might be at active end or TERMINATOR node; both are OK 13656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson nextNode = null; 13666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson nextItem = null; 13676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson break; 13686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 13696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson E item = p.item; 13706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (item != null) { 13716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson nextNode = p; 13726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson nextItem = item; 13736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson break; 13746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 13756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 13766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 13776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 13786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public boolean hasNext() { 13796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return nextItem != null; 13806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 13816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 13826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public E next() { 13836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson E item = nextItem; 13846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (item == null) throw new NoSuchElementException(); 13856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson advance(); 13866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return item; 13876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 13886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 13896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public void remove() { 13906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node<E> l = lastRet; 13916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (l == null) throw new IllegalStateException(); 13926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson l.item = null; 13936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson unlink(l); 13946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson lastRet = null; 13956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 13966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 13976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 13986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** Forward iterator */ 13996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private class Itr extends AbstractItr { 14006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node<E> startNode() { return first(); } 14016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node<E> nextNode(Node<E> p) { return succ(p); } 14026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 14036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 14046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** Descending iterator */ 14056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private class DescendingItr extends AbstractItr { 14066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node<E> startNode() { return last(); } 14076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node<E> nextNode(Node<E> p) { return pred(p); } 14086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 14096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 1410e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak /** A customized variant of Spliterators.IteratorSpliterator */ 1411e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak static final class CLDSpliterator<E> implements Spliterator<E> { 1412e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak static final int MAX_BATCH = 1 << 25; // max batch array size; 1413e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak final ConcurrentLinkedDeque<E> queue; 1414e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak Node<E> current; // current node; null until initialized 1415e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak int batch; // batch size for splits 1416e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak boolean exhausted; // true when no more nodes 1417e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak CLDSpliterator(ConcurrentLinkedDeque<E> queue) { 1418e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak this.queue = queue; 1419e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 1420e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak 1421e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak public Spliterator<E> trySplit() { 1422e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak Node<E> p; 1423e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak final ConcurrentLinkedDeque<E> q = this.queue; 1424e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak int b = batch; 1425e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1; 1426e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (!exhausted && 1427e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak ((p = current) != null || (p = q.first()) != null)) { 1428e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (p.item == null && p == (p = p.next)) 1429e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak current = p = q.first(); 1430e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (p != null && p.next != null) { 1431e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak Object[] a = new Object[n]; 1432e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak int i = 0; 1433e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak do { 1434e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if ((a[i] = p.item) != null) 1435e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak ++i; 1436e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (p == (p = p.next)) 1437e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak p = q.first(); 1438e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } while (p != null && i < n); 1439e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if ((current = p) == null) 1440e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak exhausted = true; 1441e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (i > 0) { 1442e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak batch = i; 1443e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return Spliterators.spliterator 1444e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak (a, 0, i, (Spliterator.ORDERED | 1445e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak Spliterator.NONNULL | 1446e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak Spliterator.CONCURRENT)); 1447e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 1448e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 1449e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 1450e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return null; 1451e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 1452e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak 1453e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak public void forEachRemaining(Consumer<? super E> action) { 1454e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak Node<E> p; 1455e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (action == null) throw new NullPointerException(); 1456e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak final ConcurrentLinkedDeque<E> q = this.queue; 1457e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (!exhausted && 1458e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak ((p = current) != null || (p = q.first()) != null)) { 1459e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak exhausted = true; 1460e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak do { 1461e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak E e = p.item; 1462e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (p == (p = p.next)) 1463e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak p = q.first(); 1464e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (e != null) 1465e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak action.accept(e); 1466e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } while (p != null); 1467e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 1468e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 1469e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak 1470e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak public boolean tryAdvance(Consumer<? super E> action) { 1471e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak Node<E> p; 1472e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (action == null) throw new NullPointerException(); 1473e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak final ConcurrentLinkedDeque<E> q = this.queue; 1474e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (!exhausted && 1475e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak ((p = current) != null || (p = q.first()) != null)) { 1476e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak E e; 1477e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak do { 1478e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak e = p.item; 1479e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (p == (p = p.next)) 1480e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak p = q.first(); 1481e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } while (e == null && p != null); 1482e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if ((current = p) == null) 1483e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak exhausted = true; 1484e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (e != null) { 1485e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak action.accept(e); 1486e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return true; 1487e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 1488e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 1489e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return false; 1490e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 1491e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak 1492e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak public long estimateSize() { return Long.MAX_VALUE; } 1493e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak 1494e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak public int characteristics() { 1495e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return Spliterator.ORDERED | Spliterator.NONNULL | 1496e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak Spliterator.CONCURRENT; 1497e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 1498e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 1499e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak 1500e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak /** 1501e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * Returns a {@link Spliterator} over the elements in this deque. 1502e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * 1503e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * <p>The returned spliterator is 1504e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. 1505e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * 1506e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * <p>The {@code Spliterator} reports {@link Spliterator#CONCURRENT}, 1507e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}. 1508e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * 1509e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @implNote 1510e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * The {@code Spliterator} implements {@code trySplit} to permit limited 1511e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * parallelism. 1512e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * 1513e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @return a {@code Spliterator} over the elements in this deque 1514e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @since 1.8 1515e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak */ 1516e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak public Spliterator<E> spliterator() { 1517e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return new CLDSpliterator<E>(this); 1518e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 1519e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak 15206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 152191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * Saves this deque to a stream (that is, serializes it). 15226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 1523e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @param s the stream 1524e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @throws java.io.IOException if an I/O error occurs 15256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @serialData All of the elements (each an {@code E}) in 15266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * the proper order, followed by a null 15276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 15286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private void writeObject(java.io.ObjectOutputStream s) 15296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throws java.io.IOException { 15306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 15316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // Write out any hidden stuff 15326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson s.defaultWriteObject(); 15336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 15346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // Write out all elements in the proper order. 15356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (Node<E> p = first(); p != null; p = succ(p)) { 15368eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson E item = p.item; 15376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (item != null) 15386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson s.writeObject(item); 15396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 15406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 15416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // Use trailing null as sentinel 15426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson s.writeObject(null); 15436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 15446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 15456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 154691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * Reconstitutes this deque from a stream (that is, deserializes it). 1547e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @param s the stream 1548e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @throws ClassNotFoundException if the class of a serialized object 1549e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * could not be found 1550e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @throws java.io.IOException if an I/O error occurs 15516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 15526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private void readObject(java.io.ObjectInputStream s) 15536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throws java.io.IOException, ClassNotFoundException { 15546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson s.defaultReadObject(); 15558eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson 15568eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson // Read in elements until trailing null sentinel found 15578eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson Node<E> h = null, t = null; 1558e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak for (Object item; (item = s.readObject()) != null; ) { 15596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson @SuppressWarnings("unchecked") 15608eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson Node<E> newNode = new Node<E>((E) item); 15618eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson if (h == null) 15628eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson h = t = newNode; 15638eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson else { 15648eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson t.lazySetNext(newNode); 15658eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson newNode.lazySetPrev(t); 15668eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson t = newNode; 15678eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson } 15686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 15698eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson initHeadTail(h, t); 15706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 15716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 15726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private boolean casHead(Node<E> cmp, Node<E> val) { 1573e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return U.compareAndSwapObject(this, HEAD, cmp, val); 15746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 15756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 15766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private boolean casTail(Node<E> cmp, Node<E> val) { 1577e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return U.compareAndSwapObject(this, TAIL, cmp, val); 15786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 15796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 1580a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson // Unsafe mechanics 1581a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 1582e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe(); 1583e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak private static final long HEAD; 1584e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak private static final long TAIL; 1585a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson static { 1586a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson PREV_TERMINATOR = new Node<Object>(); 1587a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson PREV_TERMINATOR.next = PREV_TERMINATOR; 1588a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson NEXT_TERMINATOR = new Node<Object>(); 1589a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson NEXT_TERMINATOR.prev = NEXT_TERMINATOR; 15906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson try { 1591e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak HEAD = U.objectFieldOffset 1592e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak (ConcurrentLinkedDeque.class.getDeclaredField("head")); 1593e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak TAIL = U.objectFieldOffset 1594e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak (ConcurrentLinkedDeque.class.getDeclaredField("tail")); 1595e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } catch (ReflectiveOperationException e) { 1596a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson throw new Error(e); 15976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 15986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 15996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson} 1600