1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
229957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
329957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer *
429957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * This code is free software; you can redistribute it and/or modify it
529957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * under the terms of the GNU General Public License version 2 only, as
629957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * published by the Free Software Foundation.  Oracle designates this
729957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * particular file as subject to the "Classpath" exception as provided
829957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * by Oracle in the LICENSE file that accompanied this code.
929957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer *
1029957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * This code is distributed in the hope that it will be useful, but WITHOUT
1129957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1229957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1329957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * version 2 for more details (a copy is included in the LICENSE file that
1429957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * accompanied this code).
1529957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer *
1629957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * You should have received a copy of the GNU General Public License version
1729957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * 2 along with this work; if not, write to the Free Software Foundation,
1829957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1929957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer *
2029957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2129957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * or visit www.oracle.com if you need additional information or have any
2229957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * questions.
2329957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer */
2429957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer
2529957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer/*
2629957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * This file is available under and governed by the GNU General Public
2729957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * License version 2 only, as published by the Free Software Foundation.
2829957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * However, the following notice accompanied the original version of this
2929957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * file:
3029957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer *
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Written by Doug Lea with assistance from members of JCP JSR-166
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Expert Group and released to the public domain, as explained at
33a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * http://creativecommons.org/publicdomain/zero/1.0/
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util.concurrent;
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
38b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport java.util.AbstractQueue;
39b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport java.util.Arrays;
40b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport java.util.Collection;
41b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport java.util.Comparator;
42b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport java.util.Iterator;
43b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport java.util.NoSuchElementException;
44b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport java.util.PriorityQueue;
45b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport java.util.Queue;
46b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport java.util.SortedSet;
47b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport java.util.Spliterator;
4891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravleimport java.util.concurrent.locks.Condition;
4991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravleimport java.util.concurrent.locks.ReentrantLock;
50b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport java.util.function.Consumer;
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// BEGIN android-note
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// removed link to collections framework docs
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// END android-note
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * An unbounded {@linkplain BlockingQueue blocking queue} that uses
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the same ordering rules as class {@link PriorityQueue} and supplies
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * blocking retrieval operations.  While this queue is logically
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * unbounded, attempted additions may fail due to resource exhaustion
618eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * (causing {@code OutOfMemoryError}). This class does not permit
628eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * {@code null} elements.  A priority queue relying on {@linkplain
63bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Comparable natural ordering} also does not permit insertion of
64bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * non-comparable objects (doing so results in
658eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * {@code ClassCastException}).
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
67bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>This class and its iterator implement all of the
68bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <em>optional</em> methods of the {@link Collection} and {@link
69bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Iterator} interfaces.  The Iterator provided in method {@link
70bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * #iterator()} is <em>not</em> guaranteed to traverse the elements of
71bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * the PriorityBlockingQueue in any particular order. If you need
72bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * ordered traversal, consider using
738eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * {@code Arrays.sort(pq.toArray())}.  Also, method {@code drainTo}
74bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * can be used to <em>remove</em> some or all elements in priority
75bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * order and place them in another collection.
76bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *
77bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>Operations on this class make no guarantees about the ordering
78bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * of elements with equal priority. If you need to enforce an
79bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * ordering, you can define custom classes or comparators that use a
80bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * secondary key to break ties in primary priority values.  For
81bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * example, here is a class that applies first-in-first-out
82bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * tie-breaking to comparable elements. To use it, you would insert a
838eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * {@code new FIFOEntry(anEntry)} instead of a plain entry object.
84bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *
85b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * <pre> {@code
868eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * class FIFOEntry<E extends Comparable<? super E>>
878eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson *     implements Comparable<FIFOEntry<E>> {
888eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson *   static final AtomicLong seq = new AtomicLong(0);
89bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *   final long seqNum;
90bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *   final E entry;
91bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *   public FIFOEntry(E entry) {
92bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *     seqNum = seq.getAndIncrement();
93bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *     this.entry = entry;
94bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *   }
95bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *   public E getEntry() { return entry; }
968eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson *   public int compareTo(FIFOEntry<E> other) {
97bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *     int res = entry.compareTo(other.entry);
988eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson *     if (res == 0 && other.entry != this.entry)
998eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson *       res = (seqNum < other.seqNum ? -1 : 1);
100bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *     return res;
101bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *   }
1028eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * }}</pre>
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @since 1.5
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @author Doug Lea
106b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * @param <E> the type of elements held in this queue
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
10891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle@SuppressWarnings("unchecked")
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class PriorityBlockingQueue<E> extends AbstractQueue<E>
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    implements BlockingQueue<E>, java.io.Serializable {
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final long serialVersionUID = 5595510919245408276L;
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1138eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    /*
1148eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * The implementation uses an array-based binary heap, with public
1158eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * operations protected with a single lock. However, allocation
1168eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * during resizing uses a simple spinlock (used only while not
1178eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * holding main lock) in order to allow takes to operate
1188eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * concurrently with allocation.  This avoids repeated
1198eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * postponement of waiting consumers and consequent element
1208eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * build-up. The need to back away from lock during allocation
1218eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * makes it impossible to simply wrap delegated
1228eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * java.util.PriorityQueue operations within a lock, as was done
1238eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * in a previous version of this class. To maintain
1248eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * interoperability, a plain PriorityQueue is still used during
125a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson     * serialization, which maintains compatibility at the expense of
1268eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * transiently doubling overhead.
1278eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     */
1288eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson
1298eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    /**
1308eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * Default array capacity.
1318eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     */
1328eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    private static final int DEFAULT_INITIAL_CAPACITY = 11;
1338eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson
1348eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    /**
1358eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * The maximum size of array to allocate.
1368eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * Some VMs reserve some header words in an array.
1378eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * Attempts to allocate larger arrays may result in
1388eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * OutOfMemoryError: Requested array size exceeds VM limit
1398eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     */
1408eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
1418eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson
1428eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    /**
1438eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * Priority queue represented as a balanced binary heap: the two
1448eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * children of queue[n] are queue[2*n+1] and queue[2*(n+1)].  The
1458eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * priority queue is ordered by comparator, or by the elements'
1468eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * natural ordering, if comparator is null: For each node n in the
1478eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * heap and each descendant d of n, n <= d.  The element with the
1488eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * lowest value is in queue[0], assuming the queue is nonempty.
1498eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     */
1508eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    private transient Object[] queue;
1518eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson
1528eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    /**
1538eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * The number of elements in the priority queue.
1548eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     */
1558eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    private transient int size;
1568eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson
1578eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    /**
1588eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * The comparator, or null if priority queue uses elements'
1598eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * natural ordering.
1608eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     */
1618eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    private transient Comparator<? super E> comparator;
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
164b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * Lock used for all public operations.
1658eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     */
1668eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    private final ReentrantLock lock;
1678eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson
1688eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    /**
169b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * Condition for blocking when empty.
1708eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     */
1718eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    private final Condition notEmpty;
1728eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson
1738eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    /**
1748eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * Spinlock for allocation, acquired via CAS.
1758eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     */
1768eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    private transient volatile int allocationSpinLock;
1778eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson
1788eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    /**
1798eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * A plain PriorityQueue used only for serialization,
1808eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * to maintain compatibility with previous versions
1818eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * of this class. Non-null only during serialization/deserialization.
1828eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     */
183a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson    private PriorityQueue<E> q;
1848eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson
1858eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    /**
1868eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * Creates a {@code PriorityBlockingQueue} with the default
187bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * initial capacity (11) that orders its elements according to
188bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * their {@linkplain Comparable natural ordering}.
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public PriorityBlockingQueue() {
1918eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        this(DEFAULT_INITIAL_CAPACITY, null);
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1958eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * Creates a {@code PriorityBlockingQueue} with the specified
196bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * initial capacity that orders its elements according to their
197bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * {@linkplain Comparable natural ordering}.
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
199bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param initialCapacity the initial capacity for this priority queue
2008eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * @throws IllegalArgumentException if {@code initialCapacity} is less
201bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         than 1
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public PriorityBlockingQueue(int initialCapacity) {
2048eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        this(initialCapacity, null);
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2088eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * Creates a {@code PriorityBlockingQueue} with the specified initial
209bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * capacity that orders its elements according to the specified
210bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * comparator.
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
212bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param initialCapacity the initial capacity for this priority queue
213bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param  comparator the comparator that will be used to order this
214bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         priority queue.  If {@code null}, the {@linkplain Comparable
215bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         natural ordering} of the elements will be used.
2168eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * @throws IllegalArgumentException if {@code initialCapacity} is less
217bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         than 1
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public PriorityBlockingQueue(int initialCapacity,
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                 Comparator<? super E> comparator) {
2218eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        if (initialCapacity < 1)
2228eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            throw new IllegalArgumentException();
2238eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        this.lock = new ReentrantLock();
2248eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        this.notEmpty = lock.newCondition();
2258eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        this.comparator = comparator;
2268eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        this.queue = new Object[initialCapacity];
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2308eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * Creates a {@code PriorityBlockingQueue} containing the elements
231bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * in the specified collection.  If the specified collection is a
232edf43d27e240d82106f39ae91404963c23987234Narayan Kamath     * {@link SortedSet} or a {@link PriorityQueue}, this
233bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * priority queue will be ordered according to the same ordering.
234bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Otherwise, this priority queue will be ordered according to the
235bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * {@linkplain Comparable natural ordering} of its elements.
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
237bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param  c the collection whose elements are to be placed
238bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         into this priority queue
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ClassCastException if elements of the specified collection
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         cannot be compared to one another according to the priority
241bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         queue's ordering
242bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws NullPointerException if the specified collection or any
243bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         of its elements are null
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public PriorityBlockingQueue(Collection<? extends E> c) {
2468eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        this.lock = new ReentrantLock();
2478eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        this.notEmpty = lock.newCondition();
2488eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        boolean heapify = true; // true if not known to be in heap order
2498eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        boolean screen = true;  // true if must screen for nulls
2508eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        if (c instanceof SortedSet<?>) {
2518eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            SortedSet<? extends E> ss = (SortedSet<? extends E>) c;
2528eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            this.comparator = (Comparator<? super E>) ss.comparator();
2538eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            heapify = false;
2548eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        }
2558eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        else if (c instanceof PriorityBlockingQueue<?>) {
2568eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            PriorityBlockingQueue<? extends E> pq =
2578eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                (PriorityBlockingQueue<? extends E>) c;
2588eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            this.comparator = (Comparator<? super E>) pq.comparator();
2598eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            screen = false;
2608eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            if (pq.getClass() == PriorityBlockingQueue.class) // exact match
2618eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                heapify = false;
2628eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        }
2638eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        Object[] a = c.toArray();
2648eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        int n = a.length;
2658eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        // If c.toArray incorrectly doesn't return Object[], copy it.
2668eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        if (a.getClass() != Object[].class)
2678eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            a = Arrays.copyOf(a, n, Object[].class);
2688eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        if (screen && (n == 1 || this.comparator != null)) {
2698eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            for (int i = 0; i < n; ++i)
2708eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                if (a[i] == null)
2718eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                    throw new NullPointerException();
2728eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        }
2738eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        this.queue = a;
2748eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        this.size = n;
2758eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        if (heapify)
2768eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            heapify();
2778eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    }
2788eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson
2798eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    /**
2808eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * Tries to grow array to accommodate at least one more element
2818eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * (but normally expand by about 50%), giving up (allowing retry)
2828eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * on contention (which we expect to be rare). Call only while
2838eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * holding lock.
2848eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     *
2858eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * @param array the heap array
2868eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * @param oldCap the length of the array
2878eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     */
2888eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    private void tryGrow(Object[] array, int oldCap) {
2898eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        lock.unlock(); // must release and then re-acquire main lock
2908eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        Object[] newArray = null;
2918eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        if (allocationSpinLock == 0 &&
292b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            U.compareAndSwapInt(this, ALLOCATIONSPINLOCK, 0, 1)) {
2938eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            try {
2948eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                int newCap = oldCap + ((oldCap < 64) ?
2958eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                                       (oldCap + 2) : // grow faster if small
2968eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                                       (oldCap >> 1));
2978eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                if (newCap - MAX_ARRAY_SIZE > 0) {    // possible overflow
2988eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                    int minCap = oldCap + 1;
2998eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                    if (minCap < 0 || minCap > MAX_ARRAY_SIZE)
3008eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                        throw new OutOfMemoryError();
3018eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                    newCap = MAX_ARRAY_SIZE;
3028eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                }
3038eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                if (newCap > oldCap && queue == array)
3048eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                    newArray = new Object[newCap];
3058eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            } finally {
3068eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                allocationSpinLock = 0;
3078eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            }
3088eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        }
3098eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        if (newArray == null) // back off if another thread is allocating
3108eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            Thread.yield();
3118eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        lock.lock();
3128eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        if (newArray != null && queue == array) {
3138eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            queue = newArray;
3148eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            System.arraycopy(array, 0, newArray, 0, oldCap);
3158eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        }
3168eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    }
3178eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson
3188eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    /**
3198eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * Mechanics for poll().  Call only while holding lock.
3208eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     */
321a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson    private E dequeue() {
3228eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        int n = size - 1;
3238eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        if (n < 0)
324a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson            return null;
3258eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        else {
3268eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            Object[] array = queue;
327a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson            E result = (E) array[0];
3288eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            E x = (E) array[n];
3298eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            array[n] = null;
3308eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            Comparator<? super E> cmp = comparator;
3318eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            if (cmp == null)
3328eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                siftDownComparable(0, x, array, n);
3338eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            else
3348eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                siftDownUsingComparator(0, x, array, n, cmp);
3358eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            size = n;
336a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson            return result;
3378eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        }
3388eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    }
3398eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson
3408eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    /**
3418eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * Inserts item x at position k, maintaining heap invariant by
3428eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * promoting x up the tree until it is greater than or equal to
3438eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * its parent, or is the root.
3448eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     *
3458eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * To simplify and speed up coercions and comparisons. the
3468eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * Comparable and Comparator versions are separated into different
3478eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * methods that are otherwise identical. (Similarly for siftDown.)
3488eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * These methods are static, with heap state as arguments, to
3498eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * simplify use in light of possible comparator exceptions.
3508eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     *
3518eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * @param k the position to fill
3528eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * @param x the item to insert
3538eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * @param array the heap array
3548eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     */
3558eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    private static <T> void siftUpComparable(int k, T x, Object[] array) {
3568eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        Comparable<? super T> key = (Comparable<? super T>) x;
3578eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        while (k > 0) {
3588eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            int parent = (k - 1) >>> 1;
3598eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            Object e = array[parent];
3608eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            if (key.compareTo((T) e) >= 0)
3618eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                break;
3628eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            array[k] = e;
3638eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            k = parent;
3648eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        }
3658eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        array[k] = key;
3668eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    }
3678eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson
3688eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    private static <T> void siftUpUsingComparator(int k, T x, Object[] array,
3698eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                                       Comparator<? super T> cmp) {
3708eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        while (k > 0) {
3718eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            int parent = (k - 1) >>> 1;
3728eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            Object e = array[parent];
3738eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            if (cmp.compare(x, (T) e) >= 0)
3748eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                break;
3758eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            array[k] = e;
3768eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            k = parent;
3778eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        }
3788eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        array[k] = x;
3798eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    }
3808eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson
3818eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    /**
3828eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * Inserts item x at position k, maintaining heap invariant by
3838eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * demoting x down the tree repeatedly until it is less than or
3848eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * equal to its children or is a leaf.
3858eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     *
3868eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * @param k the position to fill
3878eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * @param x the item to insert
3888eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * @param array the heap array
3898eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * @param n heap size
3908eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     */
3918eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    private static <T> void siftDownComparable(int k, T x, Object[] array,
3928eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                                               int n) {
39391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle        if (n > 0) {
39491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle            Comparable<? super T> key = (Comparable<? super T>)x;
39591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle            int half = n >>> 1;           // loop while a non-leaf
39691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle            while (k < half) {
39791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                int child = (k << 1) + 1; // assume left child is least
39891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                Object c = array[child];
39991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                int right = child + 1;
40091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                if (right < n &&
40191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                    ((Comparable<? super T>) c).compareTo((T) array[right]) > 0)
40291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                    c = array[child = right];
40391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                if (key.compareTo((T) c) <= 0)
40491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                    break;
40591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                array[k] = c;
40691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                k = child;
40791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle            }
40891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle            array[k] = key;
4098eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        }
4108eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    }
4118eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson
4128eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    private static <T> void siftDownUsingComparator(int k, T x, Object[] array,
4138eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                                                    int n,
4148eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                                                    Comparator<? super T> cmp) {
41591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle        if (n > 0) {
41691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle            int half = n >>> 1;
41791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle            while (k < half) {
41891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                int child = (k << 1) + 1;
41991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                Object c = array[child];
42091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                int right = child + 1;
42191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                if (right < n && cmp.compare((T) c, (T) array[right]) > 0)
42291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                    c = array[child = right];
42391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                if (cmp.compare(x, (T) c) <= 0)
42491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                    break;
42591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                array[k] = c;
42691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                k = child;
42791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle            }
42891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle            array[k] = x;
4298eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        }
4308eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    }
4318eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson
4328eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    /**
4338eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * Establishes the heap invariant (described above) in the entire tree,
4348eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * assuming nothing about the order of the elements prior to the call.
4358eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     */
4368eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    private void heapify() {
4378eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        Object[] array = queue;
4388eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        int n = size;
4398eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        int half = (n >>> 1) - 1;
4408eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        Comparator<? super E> cmp = comparator;
4418eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        if (cmp == null) {
4428eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            for (int i = half; i >= 0; i--)
4438eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                siftDownComparable(i, (E) array[i], array, n);
4448eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        }
4458eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        else {
4468eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            for (int i = half; i >= 0; i--)
4478eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                siftDownUsingComparator(i, (E) array[i], array, n, cmp);
4488eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        }
449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
452bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Inserts the specified element into this priority queue.
453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
454bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param e the element to add
4558eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * @return {@code true} (as specified by {@link Collection#add})
456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ClassCastException if the specified element cannot be compared
457bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         with elements currently in the priority queue according to the
458bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         priority queue's ordering
459bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws NullPointerException if the specified element is null
460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
461bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    public boolean add(E e) {
462bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return offer(e);
463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Inserts the specified element into this priority queue.
4678eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * As the queue is unbounded, this method will never return {@code false}.
468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
469bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param e the element to add
4708eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * @return {@code true} (as specified by {@link Queue#offer})
471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ClassCastException if the specified element cannot be compared
472bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         with elements currently in the priority queue according to the
473bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         priority queue's ordering
474bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws NullPointerException if the specified element is null
475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
476bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    public boolean offer(E e) {
4778eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        if (e == null)
4788eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            throw new NullPointerException();
479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final ReentrantLock lock = this.lock;
480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        lock.lock();
4818eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        int n, cap;
4828eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        Object[] array;
4838eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        while ((n = size) >= (cap = (array = queue).length))
4848eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            tryGrow(array, cap);
485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
4868eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            Comparator<? super E> cmp = comparator;
4878eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            if (cmp == null)
4888eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                siftUpComparable(n, e, array);
4898eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            else
4908eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                siftUpUsingComparator(n, e, array, cmp);
4918eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            size = n + 1;
492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            notEmpty.signal();
493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } finally {
494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            lock.unlock();
495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
4968eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        return true;
497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
5008eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * Inserts the specified element into this priority queue.
5018eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * As the queue is unbounded, this method will never block.
502bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
503bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param e the element to add
504bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws ClassCastException if the specified element cannot be compared
505bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         with elements currently in the priority queue according to the
506bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         priority queue's ordering
507bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws NullPointerException if the specified element is null
508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
509bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    public void put(E e) {
510bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        offer(e); // never need to block
511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
5148eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * Inserts the specified element into this priority queue.
5158eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * As the queue is unbounded, this method will never block or
5168eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * return {@code false}.
517bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
518bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param e the element to add
519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param timeout This parameter is ignored as the method never blocks
520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param unit This parameter is ignored as the method never blocks
5218eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * @return {@code true} (as specified by
522a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson     *  {@link BlockingQueue#offer(Object,long,TimeUnit) BlockingQueue.offer})
523bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws ClassCastException if the specified element cannot be compared
524bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         with elements currently in the priority queue according to the
525bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         priority queue's ordering
526bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws NullPointerException if the specified element is null
527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
528bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    public boolean offer(E e, long timeout, TimeUnit unit) {
529bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return offer(e); // never need to block
530bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
531bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
532bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    public E poll() {
533bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        final ReentrantLock lock = this.lock;
534bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        lock.lock();
535bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        try {
536a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson            return dequeue();
537bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        } finally {
538bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            lock.unlock();
539bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        }
540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public E take() throws InterruptedException {
543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final ReentrantLock lock = this.lock;
544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        lock.lockInterruptibly();
5458eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        E result;
546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
547a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson            while ( (result = dequeue()) == null)
5488eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                notEmpty.await();
549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } finally {
550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            lock.unlock();
551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
5528eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        return result;
553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public E poll(long timeout, TimeUnit unit) throws InterruptedException {
556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long nanos = unit.toNanos(timeout);
557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final ReentrantLock lock = this.lock;
558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        lock.lockInterruptibly();
5598eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        E result;
560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
561a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson            while ( (result = dequeue()) == null && nanos > 0)
5628eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                nanos = notEmpty.awaitNanos(nanos);
563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } finally {
564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            lock.unlock();
565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
5668eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        return result;
567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public E peek() {
570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final ReentrantLock lock = this.lock;
571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        lock.lock();
572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
573a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson            return (size == 0) ? null : (E) queue[0];
574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } finally {
575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            lock.unlock();
576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
579bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
580bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Returns the comparator used to order the elements in this queue,
5818eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * or {@code null} if this queue uses the {@linkplain Comparable
582bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * natural ordering} of its elements.
583bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
584bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return the comparator used to order the elements in this queue,
5858eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     *         or {@code null} if this queue uses the natural
586bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         ordering of its elements
587bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
588bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    public Comparator<? super E> comparator() {
5898eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        return comparator;
590bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
591bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int size() {
593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final ReentrantLock lock = this.lock;
594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        lock.lock();
595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
5968eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            return size;
597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } finally {
598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            lock.unlock();
599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
6038eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * Always returns {@code Integer.MAX_VALUE} because
6048eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * a {@code PriorityBlockingQueue} is not capacity constrained.
6058eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * @return {@code Integer.MAX_VALUE} always
606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int remainingCapacity() {
608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return Integer.MAX_VALUE;
609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
6118eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    private int indexOf(Object o) {
6128eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        if (o != null) {
6138eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            Object[] array = queue;
6148eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            int n = size;
6158eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            for (int i = 0; i < n; i++)
6168eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                if (o.equals(array[i]))
6178eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                    return i;
6188eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        }
6198eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        return -1;
6208eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    }
6218eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson
6228eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    /**
6238eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * Removes the ith element from queue.
6248eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     */
6258eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    private void removeAt(int i) {
6268eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        Object[] array = queue;
6278eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        int n = size - 1;
6288eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        if (n == i) // removed last element
6298eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            array[i] = null;
6308eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        else {
6318eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            E moved = (E) array[n];
6328eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            array[n] = null;
6338eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            Comparator<? super E> cmp = comparator;
6348eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            if (cmp == null)
6358eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                siftDownComparable(i, moved, array, n);
6368eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            else
6378eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                siftDownUsingComparator(i, moved, array, n, cmp);
6388eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            if (array[i] == moved) {
6398eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                if (cmp == null)
6408eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                    siftUpComparable(i, moved, array);
6418eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                else
6428eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                    siftUpUsingComparator(i, moved, array, cmp);
6438eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            }
6448eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        }
6458eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        size = n;
6468eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    }
6478eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson
648bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
649bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Removes a single instance of the specified element from this queue,
650bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * if it is present.  More formally, removes an element {@code e} such
651bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * that {@code o.equals(e)}, if this queue contains one or more such
652bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * elements.  Returns {@code true} if and only if this queue contained
653bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * the specified element (or equivalently, if this queue changed as a
654bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * result of the call).
655bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
656bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param o element to be removed from this queue, if present
6578eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * @return {@code true} if this queue changed as a result of the call
658bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean remove(Object o) {
660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final ReentrantLock lock = this.lock;
661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        lock.lock();
662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
6638eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            int i = indexOf(o);
664a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson            if (i == -1)
665a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson                return false;
666a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson            removeAt(i);
667a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson            return true;
6688eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        } finally {
6698eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            lock.unlock();
6708eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        }
6718eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    }
6728eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson
6738eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    /**
674b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * Identity-based version for use in Itr.remove.
6758eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     */
676a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson    void removeEQ(Object o) {
6778eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        final ReentrantLock lock = this.lock;
6788eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        lock.lock();
6798eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        try {
6808eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            Object[] array = queue;
681a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson            for (int i = 0, n = size; i < n; i++) {
6828eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                if (o == array[i]) {
6838eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                    removeAt(i);
6848eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                    break;
6858eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                }
6868eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            }
687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } finally {
688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            lock.unlock();
689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
692bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
693bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Returns {@code true} if this queue contains the specified element.
694bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * More formally, returns {@code true} if and only if this queue contains
695bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * at least one element {@code e} such that {@code o.equals(e)}.
696bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
697bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param o object to be checked for containment in this queue
6988eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * @return {@code true} if this queue contains the specified element
699bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean contains(Object o) {
701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final ReentrantLock lock = this.lock;
702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        lock.lock();
703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
704a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson            return indexOf(o) != -1;
705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } finally {
706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            lock.unlock();
707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toString() {
711b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        return Helpers.collectionToString(this);
712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
714bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
715bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws UnsupportedOperationException {@inheritDoc}
716bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws ClassCastException            {@inheritDoc}
717bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws NullPointerException          {@inheritDoc}
718bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws IllegalArgumentException      {@inheritDoc}
719bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int drainTo(Collection<? super E> c) {
721a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson        return drainTo(c, Integer.MAX_VALUE);
722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
724bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
725bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws UnsupportedOperationException {@inheritDoc}
726bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws ClassCastException            {@inheritDoc}
727bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws NullPointerException          {@inheritDoc}
728bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws IllegalArgumentException      {@inheritDoc}
729bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int drainTo(Collection<? super E> c, int maxElements) {
731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (c == null)
732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new NullPointerException();
733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (c == this)
734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IllegalArgumentException();
735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (maxElements <= 0)
736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return 0;
737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final ReentrantLock lock = this.lock;
738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        lock.lock();
739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
740a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson            int n = Math.min(size, maxElements);
741a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson            for (int i = 0; i < n; i++) {
742a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson                c.add((E) queue[0]); // In this order, in case add() throws.
743a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson                dequeue();
744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return n;
746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } finally {
747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            lock.unlock();
748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
752bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Atomically removes all of the elements from this queue.
753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The queue will be empty after this call returns.
754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void clear() {
756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final ReentrantLock lock = this.lock;
757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        lock.lock();
758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
7598eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            Object[] array = queue;
7608eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            int n = size;
7618eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            size = 0;
7628eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            for (int i = 0; i < n; i++)
7638eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                array[i] = null;
764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } finally {
765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            lock.unlock();
766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
769bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
770b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * Returns an array containing all of the elements in this queue.
771b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * The returned array elements are in no particular order.
772b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     *
773b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * <p>The returned array will be "safe" in that no references to it are
774b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * maintained by this queue.  (In other words, this method must allocate
775b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * a new array).  The caller is thus free to modify the returned array.
776b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     *
777b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * <p>This method acts as bridge between array-based and collection-based
778b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * APIs.
779b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     *
780b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * @return an array containing all of the elements in this queue
781b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     */
782b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    public Object[] toArray() {
783b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        final ReentrantLock lock = this.lock;
784b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        lock.lock();
785b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        try {
786b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            return Arrays.copyOf(queue, size);
787b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        } finally {
788b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            lock.unlock();
789b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        }
790b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
791b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
792b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    /**
793bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Returns an array containing all of the elements in this queue; the
794bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * runtime type of the returned array is that of the specified array.
795bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * The returned array elements are in no particular order.
796bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * If the queue fits in the specified array, it is returned therein.
797bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Otherwise, a new array is allocated with the runtime type of the
798bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * specified array and the size of this queue.
799bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
800bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <p>If this queue fits in the specified array with room to spare
801bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * (i.e., the array has more elements than this queue), the element in
802bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * the array immediately following the end of the queue is set to
8038eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * {@code null}.
804bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
805bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <p>Like the {@link #toArray()} method, this method acts as bridge between
806bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * array-based and collection-based APIs.  Further, this method allows
807bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * precise control over the runtime type of the output array, and may,
808bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * under certain circumstances, be used to save allocation costs.
809bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
8108eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * <p>Suppose {@code x} is a queue known to contain only strings.
811bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * The following code can be used to dump the queue into a newly
8128eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * allocated array of {@code String}:
813bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
814b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
815bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
8168eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * Note that {@code toArray(new Object[0])} is identical in function to
8178eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * {@code toArray()}.
818bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
819bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param a the array into which the elements of the queue are to
820bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *          be stored, if it is big enough; otherwise, a new array of the
821bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *          same runtime type is allocated for this purpose
822bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return an array containing all of the elements in this queue
823bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws ArrayStoreException if the runtime type of the specified array
824bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         is not a supertype of the runtime type of every element in
825bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         this queue
826bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws NullPointerException if the specified array is null
827bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public <T> T[] toArray(T[] a) {
829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final ReentrantLock lock = this.lock;
830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        lock.lock();
831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
8328eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            int n = size;
8338eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            if (a.length < n)
8348eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                // Make a new array of a's runtime type, but my contents:
8358eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                return (T[]) Arrays.copyOf(queue, size, a.getClass());
8368eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            System.arraycopy(queue, 0, a, 0, n);
8378eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            if (a.length > n)
8388eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                a[n] = null;
8398eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            return a;
840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } finally {
841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            lock.unlock();
842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns an iterator over the elements in this queue. The
847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * iterator does not return the elements in any particular order.
8488eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     *
849b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * <p>The returned iterator is
850b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
852bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return an iterator over the elements in this queue
853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
854adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Iterator<E> iterator() {
855bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return new Itr(toArray());
856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
857adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
858bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
859bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Snapshot iterator that works off copy of underlying q array.
860bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
8618eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    final class Itr implements Iterator<E> {
862bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        final Object[] array; // Array of all elements
863a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson        int cursor;           // index of next element to return
864bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        int lastRet;          // index of last element, or -1 if no such
865bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
866bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        Itr(Object[] array) {
867bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            lastRet = -1;
868bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            this.array = array;
869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
870adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public boolean hasNext() {
872bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            return cursor < array.length;
873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public E next() {
876bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (cursor >= array.length)
877bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                throw new NoSuchElementException();
878bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            lastRet = cursor;
879bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            return (E)array[cursor++];
880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void remove() {
883bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (lastRet < 0)
884bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                throw new IllegalStateException();
8858eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            removeEQ(array[lastRet]);
886bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            lastRet = -1;
887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
89191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * Saves this queue to a stream (that is, serializes it).
89291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     *
89391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * For compatibility with previous version of this class, elements
89491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * are first copied to a java.util.PriorityQueue, which is then
89591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * serialized.
896b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     *
897b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * @param s the stream
898b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * @throws java.io.IOException if an I/O error occurs
899adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void writeObject(java.io.ObjectOutputStream s)
901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throws java.io.IOException {
902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        lock.lock();
903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
904a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson            // avoid zero capacity argument
905a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson            q = new PriorityQueue<E>(Math.max(size, 1), comparator);
9068eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            q.addAll(this);
907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            s.defaultWriteObject();
908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } finally {
9098eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            q = null;
910adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            lock.unlock();
911adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
9148eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    /**
91591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * Reconstitutes this queue from a stream (that is, deserializes it).
916b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * @param s the stream
917b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * @throws ClassNotFoundException if the class of a serialized object
918b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     *         could not be found
919b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * @throws java.io.IOException if an I/O error occurs
9208eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     */
9218eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    private void readObject(java.io.ObjectInputStream s)
9228eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        throws java.io.IOException, ClassNotFoundException {
9238eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        try {
9248eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            s.defaultReadObject();
9258eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            this.queue = new Object[q.size()];
9268eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            comparator = q.comparator();
9278eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            addAll(q);
9288eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        } finally {
9298eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            q = null;
9308eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        }
9318eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    }
9328eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson
933b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    // Similar to Collections.ArraySnapshotSpliterator but avoids
934b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    // commitment to toArray until needed
935b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    static final class PBQSpliterator<E> implements Spliterator<E> {
936b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        final PriorityBlockingQueue<E> queue;
937b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        Object[] array;
938b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        int index;
939b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        int fence;
940b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
941b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        PBQSpliterator(PriorityBlockingQueue<E> queue, Object[] array,
942b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                       int index, int fence) {
943b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            this.queue = queue;
944b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            this.array = array;
945b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            this.index = index;
946b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            this.fence = fence;
947b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        }
948b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
949b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        final int getFence() {
950b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            int hi;
951b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            if ((hi = fence) < 0)
952b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                hi = fence = (array = queue.toArray()).length;
953b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            return hi;
954b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        }
955b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
956b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        public PBQSpliterator<E> trySplit() {
957b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
958b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            return (lo >= mid) ? null :
959b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                new PBQSpliterator<E>(queue, array, lo, index = mid);
960b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        }
961b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
962b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        @SuppressWarnings("unchecked")
963b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        public void forEachRemaining(Consumer<? super E> action) {
964b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            Object[] a; int i, hi; // hoist accesses and checks from loop
965b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            if (action == null)
966b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                throw new NullPointerException();
967b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            if ((a = array) == null)
968b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                fence = (a = queue.toArray()).length;
969b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            if ((hi = fence) <= a.length &&
970b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                (i = index) >= 0 && i < (index = hi)) {
971b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                do { action.accept((E)a[i]); } while (++i < hi);
972b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            }
973b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        }
974b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
975b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        public boolean tryAdvance(Consumer<? super E> action) {
976b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            if (action == null)
977b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                throw new NullPointerException();
978b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            if (getFence() > index && index >= 0) {
979b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                @SuppressWarnings("unchecked") E e = (E) array[index++];
980b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                action.accept(e);
981b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                return true;
982b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            }
983b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            return false;
984b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        }
985b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
986b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        public long estimateSize() { return (long)(getFence() - index); }
987b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
988b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        public int characteristics() {
989b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            return Spliterator.NONNULL | Spliterator.SIZED | Spliterator.SUBSIZED;
990b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        }
991b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
992b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
993b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    /**
994b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * Returns a {@link Spliterator} over the elements in this queue.
995b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     *
996b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * <p>The returned spliterator is
997b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
998b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     *
999b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * <p>The {@code Spliterator} reports {@link Spliterator#SIZED} and
1000b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * {@link Spliterator#NONNULL}.
1001b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     *
1002b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * @implNote
1003b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * The {@code Spliterator} additionally reports {@link Spliterator#SUBSIZED}.
1004b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     *
1005b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * @return a {@code Spliterator} over the elements in this queue
1006b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * @since 1.8
1007b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     */
1008b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    public Spliterator<E> spliterator() {
1009b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        return new PBQSpliterator<E>(this, null, 0, -1);
1010b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
1011b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
10128eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    // Unsafe mechanics
1013b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
1014b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    private static final long ALLOCATIONSPINLOCK;
1015a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson    static {
10168eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        try {
1017b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            ALLOCATIONSPINLOCK = U.objectFieldOffset
1018b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                (PriorityBlockingQueue.class.getDeclaredField("allocationSpinLock"));
1019b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        } catch (ReflectiveOperationException e) {
1020a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson            throw new Error(e);
10218eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        }
10228eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    }
1023adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
1024