1 /*
   2  * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.util;
  27 
  28 import java.util.function.Consumer;
  29 import java.util.function.Predicate;
  30 import jdk.internal.access.SharedSecrets;
  31 import jdk.internal.util.ArraysSupport;
  32 
  33 /**
  34  * An unbounded priority {@linkplain Queue queue} based on a priority heap.
  35  * The elements of the priority queue are ordered according to their
  36  * {@linkplain Comparable natural ordering}, or by a {@link Comparator}
  37  * provided at queue construction time, depending on which constructor is
  38  * used.  A priority queue does not permit {@code null} elements.
  39  * A priority queue relying on natural ordering also does not permit
  40  * insertion of non-comparable objects (doing so may result in
  41  * {@code ClassCastException}).
  42  *
  43  * <p>The <em>head</em> of this queue is the <em>least</em> element
  44  * with respect to the specified ordering.  If multiple elements are
  45  * tied for least value, the head is one of those elements -- ties are
  46  * broken arbitrarily.  The queue retrieval operations {@code poll},
  47  * {@code remove}, {@code peek}, and {@code element} access the
  48  * element at the head of the queue.
  49  *
  50  * <p>A priority queue is unbounded, but has an internal
  51  * <i>capacity</i> governing the size of an array used to store the
  52  * elements on the queue.  It is always at least as large as the queue
  53  * size.  As elements are added to a priority queue, its capacity
  54  * grows automatically.  The details of the growth policy are not
  55  * specified.
  56  *
  57  * <p>This class and its iterator implement all of the
  58  * <em>optional</em> methods of the {@link Collection} and {@link
  59  * Iterator} interfaces.  The Iterator provided in method {@link
  60  * #iterator()} and the Spliterator provided in method {@link #spliterator()}
  61  * are <em>not</em> guaranteed to traverse the elements of
  62  * the priority queue in any particular order. If you need ordered
  63  * traversal, consider using {@code Arrays.sort(pq.toArray())}.
  64  *
  65  * <p><strong>Note that this implementation is not synchronized.</strong>
  66  * Multiple threads should not access a {@code PriorityQueue}
  67  * instance concurrently if any of the threads modifies the queue.
  68  * Instead, use the thread-safe {@link
  69  * java.util.concurrent.PriorityBlockingQueue} class.
  70  *
  71  * <p>Implementation note: this implementation provides
  72  * O(log(n)) time for the enqueuing and dequeuing methods
  73  * ({@code offer}, {@code poll}, {@code remove()} and {@code add});
  74  * linear time for the {@code remove(Object)} and {@code contains(Object)}
  75  * methods; and constant time for the retrieval methods
  76  * ({@code peek}, {@code element}, and {@code size}).
  77  *
  78  * <p>This class is a member of the
  79  * <a href="{@docRoot}/java.base/java/util/package-summary.html#CollectionsFramework">
  80  * Java Collections Framework</a>.
  81  *
  82  * @since 1.5
  83  * @author Josh Bloch, Doug Lea
  84  * @param <E> the type of elements held in this queue
  85  */
  86 @SuppressWarnings("unchecked")
  87 public class PriorityQueue<E> extends AbstractQueue<E>
  88     implements java.io.Serializable {
  89 
  90     private static final long serialVersionUID = -7720805057305804111L;
  91 
  92     private static final int DEFAULT_INITIAL_CAPACITY = 11;
  93 
  94     /**
  95      * Priority queue represented as a balanced binary heap: the two
  96      * children of queue[n] are queue[2*n+1] and queue[2*(n+1)].  The
  97      * priority queue is ordered by comparator, or by the elements'
  98      * natural ordering, if comparator is null: For each node n in the
  99      * heap and each descendant d of n, n <= d.  The element with the
 100      * lowest value is in queue[0], assuming the queue is nonempty.
 101      */
 102     transient Object[] queue; // non-private to simplify nested class access
 103 
 104     /**
 105      * The number of elements in the priority queue.
 106      */
 107     int size;
 108 
 109     /**
 110      * The comparator, or null if priority queue uses elements'
 111      * natural ordering.
 112      */
 113     private final Comparator<? super E> comparator;
 114 
 115     /**
 116      * The number of times this priority queue has been
 117      * <i>structurally modified</i>.  See AbstractList for gory details.
 118      */
 119     transient int modCount;     // non-private to simplify nested class access
 120 
 121     /**
 122      * Creates a {@code PriorityQueue} with the default initial
 123      * capacity (11) that orders its elements according to their
 124      * {@linkplain Comparable natural ordering}.
 125      */
 126     public PriorityQueue() {
 127         this(DEFAULT_INITIAL_CAPACITY, null);
 128     }
 129 
 130     /**
 131      * Creates a {@code PriorityQueue} with the specified initial
 132      * capacity that orders its elements according to their
 133      * {@linkplain Comparable natural ordering}.
 134      *
 135      * @param initialCapacity the initial capacity for this priority queue
 136      * @throws IllegalArgumentException if {@code initialCapacity} is less
 137      *         than 1
 138      */
 139     public PriorityQueue(int initialCapacity) {
 140         this(initialCapacity, null);
 141     }
 142 
 143     /**
 144      * Creates a {@code PriorityQueue} with the default initial capacity and
 145      * whose elements are ordered according to the specified comparator.
 146      *
 147      * @param  comparator the comparator that will be used to order this
 148      *         priority queue.  If {@code null}, the {@linkplain Comparable
 149      *         natural ordering} of the elements will be used.
 150      * @since 1.8
 151      */
 152     public PriorityQueue(Comparator<? super E> comparator) {
 153         this(DEFAULT_INITIAL_CAPACITY, comparator);
 154     }
 155 
 156     /**
 157      * Creates a {@code PriorityQueue} with the specified initial capacity
 158      * that orders its elements according to the specified comparator.
 159      *
 160      * @param  initialCapacity the initial capacity for this priority queue
 161      * @param  comparator the comparator that will be used to order this
 162      *         priority queue.  If {@code null}, the {@linkplain Comparable
 163      *         natural ordering} of the elements will be used.
 164      * @throws IllegalArgumentException if {@code initialCapacity} is
 165      *         less than 1
 166      */
 167     public PriorityQueue(int initialCapacity,
 168                          Comparator<? super E> comparator) {
 169         // Note: This restriction of at least one is not actually needed,
 170         // but continues for 1.5 compatibility
 171         if (initialCapacity < 1)
 172             throw new IllegalArgumentException();
 173         this.queue = new Object[initialCapacity];
 174         this.comparator = comparator;
 175     }
 176 
 177     /**
 178      * Creates a {@code PriorityQueue} containing the elements in the
 179      * specified collection.  If the specified collection is an instance of
 180      * a {@link SortedSet} or is another {@code PriorityQueue}, this
 181      * priority queue will be ordered according to the same ordering.
 182      * Otherwise, this priority queue will be ordered according to the
 183      * {@linkplain Comparable natural ordering} of its elements.
 184      *
 185      * @param  c the collection whose elements are to be placed
 186      *         into this priority queue
 187      * @throws ClassCastException if elements of the specified collection
 188      *         cannot be compared to one another according to the priority
 189      *         queue's ordering
 190      * @throws NullPointerException if the specified collection or any
 191      *         of its elements are null
 192      */
 193     public PriorityQueue(Collection<? extends E> c) {
 194         if (c instanceof SortedSet<?>) {
 195             SortedSet<? extends E> ss = (SortedSet<? extends E>) c;
 196             this.comparator = (Comparator<? super E>) ss.comparator();
 197             initElementsFromCollection(ss);
 198         }
 199         else if (c instanceof PriorityQueue<?>) {
 200             PriorityQueue<? extends E> pq = (PriorityQueue<? extends E>) c;
 201             this.comparator = (Comparator<? super E>) pq.comparator();
 202             initFromPriorityQueue(pq);
 203         }
 204         else {
 205             this.comparator = null;
 206             initFromCollection(c);
 207         }
 208     }
 209 
 210     /**
 211      * Creates a {@code PriorityQueue} containing the elements in the
 212      * specified priority queue.  This priority queue will be
 213      * ordered according to the same ordering as the given priority
 214      * queue.
 215      *
 216      * @param  c the priority queue whose elements are to be placed
 217      *         into this priority queue
 218      * @throws ClassCastException if elements of {@code c} cannot be
 219      *         compared to one another according to {@code c}'s
 220      *         ordering
 221      * @throws NullPointerException if the specified priority queue or any
 222      *         of its elements are null
 223      */
 224     public PriorityQueue(PriorityQueue<? extends E> c) {
 225         this.comparator = (Comparator<? super E>) c.comparator();
 226         initFromPriorityQueue(c);
 227     }
 228 
 229     /**
 230      * Creates a {@code PriorityQueue} containing the elements in the
 231      * specified sorted set.   This priority queue will be ordered
 232      * according to the same ordering as the given sorted set.
 233      *
 234      * @param  c the sorted set whose elements are to be placed
 235      *         into this priority queue
 236      * @throws ClassCastException if elements of the specified sorted
 237      *         set cannot be compared to one another according to the
 238      *         sorted set's ordering
 239      * @throws NullPointerException if the specified sorted set or any
 240      *         of its elements are null
 241      */
 242     public PriorityQueue(SortedSet<? extends E> c) {
 243         this.comparator = (Comparator<? super E>) c.comparator();
 244         initElementsFromCollection(c);
 245     }
 246 
 247     /** Ensures that queue[0] exists, helping peek() and poll(). */
 248     private static Object[] ensureNonEmpty(Object[] es) {
 249         return (es.length > 0) ? es : new Object[1];
 250     }
 251 
 252     private void initFromPriorityQueue(PriorityQueue<? extends E> c) {
 253         if (c.getClass() == PriorityQueue.class) {
 254             this.queue = ensureNonEmpty(c.toArray());
 255             this.size = c.size();
 256         } else {
 257             initFromCollection(c);
 258         }
 259     }
 260 
 261     private void initElementsFromCollection(Collection<? extends E> c) {
 262         Object[] es = c.toArray();
 263         int len = es.length;
 264         // If c.toArray incorrectly doesn't return Object[], copy it.
 265         if (es.getClass() != Object[].class)
 266             es = Arrays.copyOf(es, len, Object[].class);
 267         if (len == 1 || this.comparator != null)
 268             for (Object e : es)
 269                 if (e == null)
 270                     throw new NullPointerException();
 271         this.queue = ensureNonEmpty(es);
 272         this.size = len;
 273     }
 274 
 275     /**
 276      * Initializes queue array with elements from the given Collection.
 277      *
 278      * @param c the collection
 279      */
 280     private void initFromCollection(Collection<? extends E> c) {
 281         initElementsFromCollection(c);
 282         heapify();
 283     }
 284 
 285     /**
 286      * Increases the capacity of the array.
 287      *
 288      * @param minCapacity the desired minimum capacity
 289      */
 290     private void grow(int minCapacity) {
 291         int oldCapacity = queue.length;
 292         // Double size if small; else grow by 50%
 293         int newCapacity = ArraysSupport.newCapacity(oldCapacity,
 294                 minCapacity - oldCapacity,
 295                 oldCapacity < 64 ? oldCapacity + 2 : oldCapacity >> 1);
 296         queue = Arrays.copyOf(queue, newCapacity);
 297     }
 298 
 299     /**
 300      * Inserts the specified element into this priority queue.
 301      *
 302      * @return {@code true} (as specified by {@link Collection#add})
 303      * @throws ClassCastException if the specified element cannot be
 304      *         compared with elements currently in this priority queue
 305      *         according to the priority queue's ordering
 306      * @throws NullPointerException if the specified element is null
 307      */
 308     public boolean add(E e) {
 309         return offer(e);
 310     }
 311 
 312     /**
 313      * Inserts the specified element into this priority queue.
 314      *
 315      * @return {@code true} (as specified by {@link Queue#offer})
 316      * @throws ClassCastException if the specified element cannot be
 317      *         compared with elements currently in this priority queue
 318      *         according to the priority queue's ordering
 319      * @throws NullPointerException if the specified element is null
 320      */
 321     public boolean offer(E e) {
 322         if (e == null)
 323             throw new NullPointerException();
 324         modCount++;
 325         int i = size;
 326         if (i >= queue.length)
 327             grow(i + 1);
 328         siftUp(i, e);
 329         size = i + 1;
 330         return true;
 331     }
 332 
 333     public E peek() {
 334         return (E) queue[0];
 335     }
 336 
 337     private int indexOf(Object o) {
 338         if (o != null) {
 339             final Object[] es = queue;
 340             for (int i = 0, n = size; i < n; i++)
 341                 if (o.equals(es[i]))
 342                     return i;
 343         }
 344         return -1;
 345     }
 346 
 347     /**
 348      * Removes a single instance of the specified element from this queue,
 349      * if it is present.  More formally, removes an element {@code e} such
 350      * that {@code o.equals(e)}, if this queue contains one or more such
 351      * elements.  Returns {@code true} if and only if this queue contained
 352      * the specified element (or equivalently, if this queue changed as a
 353      * result of the call).
 354      *
 355      * @param o element to be removed from this queue, if present
 356      * @return {@code true} if this queue changed as a result of the call
 357      */
 358     public boolean remove(Object o) {
 359         int i = indexOf(o);
 360         if (i == -1)
 361             return false;
 362         else {
 363             removeAt(i);
 364             return true;
 365         }
 366     }
 367 
 368     /**
 369      * Identity-based version for use in Itr.remove.
 370      *
 371      * @param o element to be removed from this queue, if present
 372      */
 373     void removeEq(Object o) {
 374         final Object[] es = queue;
 375         for (int i = 0, n = size; i < n; i++) {
 376             if (o == es[i]) {
 377                 removeAt(i);
 378                 break;
 379             }
 380         }
 381     }
 382 
 383     /**
 384      * Returns {@code true} if this queue contains the specified element.
 385      * More formally, returns {@code true} if and only if this queue contains
 386      * at least one element {@code e} such that {@code o.equals(e)}.
 387      *
 388      * @param o object to be checked for containment in this queue
 389      * @return {@code true} if this queue contains the specified element
 390      */
 391     public boolean contains(Object o) {
 392         return indexOf(o) >= 0;
 393     }
 394 
 395     /**
 396      * Returns an array containing all of the elements in this queue.
 397      * The elements are in no particular order.
 398      *
 399      * <p>The returned array will be "safe" in that no references to it are
 400      * maintained by this queue.  (In other words, this method must allocate
 401      * a new array).  The caller is thus free to modify the returned array.
 402      *
 403      * <p>This method acts as bridge between array-based and collection-based
 404      * APIs.
 405      *
 406      * @return an array containing all of the elements in this queue
 407      */
 408     public Object[] toArray() {
 409         return Arrays.copyOf(queue, size);
 410     }
 411 
 412     /**
 413      * Returns an array containing all of the elements in this queue; the
 414      * runtime type of the returned array is that of the specified array.
 415      * The returned array elements are in no particular order.
 416      * If the queue fits in the specified array, it is returned therein.
 417      * Otherwise, a new array is allocated with the runtime type of the
 418      * specified array and the size of this queue.
 419      *
 420      * <p>If the queue fits in the specified array with room to spare
 421      * (i.e., the array has more elements than the queue), the element in
 422      * the array immediately following the end of the collection is set to
 423      * {@code null}.
 424      *
 425      * <p>Like the {@link #toArray()} method, this method acts as bridge between
 426      * array-based and collection-based APIs.  Further, this method allows
 427      * precise control over the runtime type of the output array, and may,
 428      * under certain circumstances, be used to save allocation costs.
 429      *
 430      * <p>Suppose {@code x} is a queue known to contain only strings.
 431      * The following code can be used to dump the queue into a newly
 432      * allocated array of {@code String}:
 433      *
 434      * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
 435      *
 436      * Note that {@code toArray(new Object[0])} is identical in function to
 437      * {@code toArray()}.
 438      *
 439      * @param a the array into which the elements of the queue are to
 440      *          be stored, if it is big enough; otherwise, a new array of the
 441      *          same runtime type is allocated for this purpose.
 442      * @return an array containing all of the elements in this queue
 443      * @throws ArrayStoreException if the runtime type of the specified array
 444      *         is not a supertype of the runtime type of every element in
 445      *         this queue
 446      * @throws NullPointerException if the specified array is null
 447      */
 448     public <T> T[] toArray(T[] a) {
 449         final int size = this.size;
 450         if (a.length < size)
 451             // Make a new array of a's runtime type, but my contents:
 452             return (T[]) Arrays.copyOf(queue, size, a.getClass());
 453         System.arraycopy(queue, 0, a, 0, size);
 454         if (a.length > size)
 455             a[size] = null;
 456         return a;
 457     }
 458 
 459     /**
 460      * Returns an iterator over the elements in this queue. The iterator
 461      * does not return the elements in any particular order.
 462      *
 463      * @return an iterator over the elements in this queue
 464      */
 465     public Iterator<E> iterator() {
 466         return new Itr();
 467     }
 468 
 469     private final class Itr implements Iterator<E> {
 470         /**
 471          * Index (into queue array) of element to be returned by
 472          * subsequent call to next.
 473          */
 474         private int cursor;
 475 
 476         /**
 477          * Index of element returned by most recent call to next,
 478          * unless that element came from the forgetMeNot list.
 479          * Set to -1 if element is deleted by a call to remove.
 480          */
 481         private int lastRet = -1;
 482 
 483         /**
 484          * A queue of elements that were moved from the unvisited portion of
 485          * the heap into the visited portion as a result of "unlucky" element
 486          * removals during the iteration.  (Unlucky element removals are those
 487          * that require a siftup instead of a siftdown.)  We must visit all of
 488          * the elements in this list to complete the iteration.  We do this
 489          * after we've completed the "normal" iteration.
 490          *
 491          * We expect that most iterations, even those involving removals,
 492          * will not need to store elements in this field.
 493          */
 494         private ArrayDeque<E> forgetMeNot;
 495 
 496         /**
 497          * Element returned by the most recent call to next iff that
 498          * element was drawn from the forgetMeNot list.
 499          */
 500         private E lastRetElt;
 501 
 502         /**
 503          * The modCount value that the iterator believes that the backing
 504          * Queue should have.  If this expectation is violated, the iterator
 505          * has detected concurrent modification.
 506          */
 507         private int expectedModCount = modCount;
 508 
 509         Itr() {}                        // prevent access constructor creation
 510 
 511         public boolean hasNext() {
 512             return cursor < size ||
 513                 (forgetMeNot != null && !forgetMeNot.isEmpty());
 514         }
 515 
 516         public E next() {
 517             if (expectedModCount != modCount)
 518                 throw new ConcurrentModificationException();
 519             if (cursor < size)
 520                 return (E) queue[lastRet = cursor++];
 521             if (forgetMeNot != null) {
 522                 lastRet = -1;
 523                 lastRetElt = forgetMeNot.poll();
 524                 if (lastRetElt != null)
 525                     return lastRetElt;
 526             }
 527             throw new NoSuchElementException();
 528         }
 529 
 530         public void remove() {
 531             if (expectedModCount != modCount)
 532                 throw new ConcurrentModificationException();
 533             if (lastRet != -1) {
 534                 E moved = PriorityQueue.this.removeAt(lastRet);
 535                 lastRet = -1;
 536                 if (moved == null)
 537                     cursor--;
 538                 else {
 539                     if (forgetMeNot == null)
 540                         forgetMeNot = new ArrayDeque<>();
 541                     forgetMeNot.add(moved);
 542                 }
 543             } else if (lastRetElt != null) {
 544                 PriorityQueue.this.removeEq(lastRetElt);
 545                 lastRetElt = null;
 546             } else {
 547                 throw new IllegalStateException();
 548             }
 549             expectedModCount = modCount;
 550         }
 551     }
 552 
 553     public int size() {
 554         return size;
 555     }
 556 
 557     /**
 558      * Removes all of the elements from this priority queue.
 559      * The queue will be empty after this call returns.
 560      */
 561     public void clear() {
 562         modCount++;
 563         final Object[] es = queue;
 564         for (int i = 0, n = size; i < n; i++)
 565             es[i] = null;
 566         size = 0;
 567     }
 568 
 569     public E poll() {
 570         final Object[] es;
 571         final E result;
 572 
 573         if ((result = (E) ((es = queue)[0])) != null) {
 574             modCount++;
 575             final int n;
 576             final E x = (E) es[(n = --size)];
 577             es[n] = null;
 578             if (n > 0) {
 579                 final Comparator<? super E> cmp;
 580                 if ((cmp = comparator) == null)
 581                     siftDownComparable(0, x, es, n);
 582                 else
 583                     siftDownUsingComparator(0, x, es, n, cmp);
 584             }
 585         }
 586         return result;
 587     }
 588 
 589     /**
 590      * Removes the ith element from queue.
 591      *
 592      * Normally this method leaves the elements at up to i-1,
 593      * inclusive, untouched.  Under these circumstances, it returns
 594      * null.  Occasionally, in order to maintain the heap invariant,
 595      * it must swap a later element of the list with one earlier than
 596      * i.  Under these circumstances, this method returns the element
 597      * that was previously at the end of the list and is now at some
 598      * position before i. This fact is used by iterator.remove so as to
 599      * avoid missing traversing elements.
 600      */
 601     E removeAt(int i) {
 602         // assert i >= 0 && i < size;
 603         final Object[] es = queue;
 604         modCount++;
 605         int s = --size;
 606         if (s == i) // removed last element
 607             es[i] = null;
 608         else {
 609             E moved = (E) es[s];
 610             es[s] = null;
 611             siftDown(i, moved);
 612             if (es[i] == moved) {
 613                 siftUp(i, moved);
 614                 if (es[i] != moved)
 615                     return moved;
 616             }
 617         }
 618         return null;
 619     }
 620 
 621     /**
 622      * Inserts item x at position k, maintaining heap invariant by
 623      * promoting x up the tree until it is greater than or equal to
 624      * its parent, or is the root.
 625      *
 626      * To simplify and speed up coercions and comparisons, the
 627      * Comparable and Comparator versions are separated into different
 628      * methods that are otherwise identical. (Similarly for siftDown.)
 629      *
 630      * @param k the position to fill
 631      * @param x the item to insert
 632      */
 633     private void siftUp(int k, E x) {
 634         if (comparator != null)
 635             siftUpUsingComparator(k, x, queue, comparator);
 636         else
 637             siftUpComparable(k, x, queue);
 638     }
 639 
 640     private static <T> void siftUpComparable(int k, T x, Object[] es) {
 641         Comparable<? super T> key = (Comparable<? super T>) x;
 642         while (k > 0) {
 643             int parent = (k - 1) >>> 1;
 644             Object e = es[parent];
 645             if (key.compareTo((T) e) >= 0)
 646                 break;
 647             es[k] = e;
 648             k = parent;
 649         }
 650         es[k] = key;
 651     }
 652 
 653     private static <T> void siftUpUsingComparator(
 654         int k, T x, Object[] es, Comparator<? super T> cmp) {
 655         while (k > 0) {
 656             int parent = (k - 1) >>> 1;
 657             Object e = es[parent];
 658             if (cmp.compare(x, (T) e) >= 0)
 659                 break;
 660             es[k] = e;
 661             k = parent;
 662         }
 663         es[k] = x;
 664     }
 665 
 666     /**
 667      * Inserts item x at position k, maintaining heap invariant by
 668      * demoting x down the tree repeatedly until it is less than or
 669      * equal to its children or is a leaf.
 670      *
 671      * @param k the position to fill
 672      * @param x the item to insert
 673      */
 674     private void siftDown(int k, E x) {
 675         if (comparator != null)
 676             siftDownUsingComparator(k, x, queue, size, comparator);
 677         else
 678             siftDownComparable(k, x, queue, size);
 679     }
 680 
 681     private static <T> void siftDownComparable(int k, T x, Object[] es, int n) {
 682         // assert n > 0;
 683         Comparable<? super T> key = (Comparable<? super T>)x;
 684         int half = n >>> 1;           // loop while a non-leaf
 685         while (k < half) {
 686             int child = (k << 1) + 1; // assume left child is least
 687             Object c = es[child];
 688             int right = child + 1;
 689             if (right < n &&
 690                 ((Comparable<? super T>) c).compareTo((T) es[right]) > 0)
 691                 c = es[child = right];
 692             if (key.compareTo((T) c) <= 0)
 693                 break;
 694             es[k] = c;
 695             k = child;
 696         }
 697         es[k] = key;
 698     }
 699 
 700     private static <T> void siftDownUsingComparator(
 701         int k, T x, Object[] es, int n, Comparator<? super T> cmp) {
 702         // assert n > 0;
 703         int half = n >>> 1;
 704         while (k < half) {
 705             int child = (k << 1) + 1;
 706             Object c = es[child];
 707             int right = child + 1;
 708             if (right < n && cmp.compare((T) c, (T) es[right]) > 0)
 709                 c = es[child = right];
 710             if (cmp.compare(x, (T) c) <= 0)
 711                 break;
 712             es[k] = c;
 713             k = child;
 714         }
 715         es[k] = x;
 716     }
 717 
 718     /**
 719      * Establishes the heap invariant (described above) in the entire tree,
 720      * assuming nothing about the order of the elements prior to the call.
 721      * This classic algorithm due to Floyd (1964) is known to be O(size).
 722      */
 723     private void heapify() {
 724         final Object[] es = queue;
 725         int n = size, i = (n >>> 1) - 1;
 726         final Comparator<? super E> cmp;
 727         if ((cmp = comparator) == null)
 728             for (; i >= 0; i--)
 729                 siftDownComparable(i, (E) es[i], es, n);
 730         else
 731             for (; i >= 0; i--)
 732                 siftDownUsingComparator(i, (E) es[i], es, n, cmp);
 733     }
 734 
 735     /**
 736      * Returns the comparator used to order the elements in this
 737      * queue, or {@code null} if this queue is sorted according to
 738      * the {@linkplain Comparable natural ordering} of its elements.
 739      *
 740      * @return the comparator used to order this queue, or
 741      *         {@code null} if this queue is sorted according to the
 742      *         natural ordering of its elements
 743      */
 744     public Comparator<? super E> comparator() {
 745         return comparator;
 746     }
 747 
 748     /**
 749      * Saves this queue to a stream (that is, serializes it).
 750      *
 751      * @param s the stream
 752      * @throws java.io.IOException if an I/O error occurs
 753      * @serialData The length of the array backing the instance is
 754      *             emitted (int), followed by all of its elements
 755      *             (each an {@code Object}) in the proper order.
 756      */
 757     private void writeObject(java.io.ObjectOutputStream s)
 758         throws java.io.IOException {
 759         // Write out element count, and any hidden stuff
 760         s.defaultWriteObject();
 761 
 762         // Write out array length, for compatibility with 1.5 version
 763         s.writeInt(Math.max(2, size + 1));
 764 
 765         // Write out all elements in the "proper order".
 766         final Object[] es = queue;
 767         for (int i = 0, n = size; i < n; i++)
 768             s.writeObject(es[i]);
 769     }
 770 
 771     /**
 772      * Reconstitutes the {@code PriorityQueue} instance from a stream
 773      * (that is, deserializes it).
 774      *
 775      * @param s the stream
 776      * @throws ClassNotFoundException if the class of a serialized object
 777      *         could not be found
 778      * @throws java.io.IOException if an I/O error occurs
 779      */
 780     private void readObject(java.io.ObjectInputStream s)
 781         throws java.io.IOException, ClassNotFoundException {
 782         // Read in size, and any hidden stuff
 783         s.defaultReadObject();
 784 
 785         // Read in (and discard) array length
 786         s.readInt();
 787 
 788         SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, size);
 789         final Object[] es = queue = new Object[Math.max(size, 1)];
 790 
 791         // Read in all elements.
 792         for (int i = 0, n = size; i < n; i++)
 793             es[i] = s.readObject();
 794 
 795         // Elements are guaranteed to be in "proper order", but the
 796         // spec has never explained what that might be.
 797         heapify();
 798     }
 799 
 800     /**
 801      * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
 802      * and <em>fail-fast</em> {@link Spliterator} over the elements in this
 803      * queue. The spliterator does not traverse elements in any particular order
 804      * (the {@link Spliterator#ORDERED ORDERED} characteristic is not reported).
 805      *
 806      * <p>The {@code Spliterator} reports {@link Spliterator#SIZED},
 807      * {@link Spliterator#SUBSIZED}, and {@link Spliterator#NONNULL}.
 808      * Overriding implementations should document the reporting of additional
 809      * characteristic values.
 810      *
 811      * @return a {@code Spliterator} over the elements in this queue
 812      * @since 1.8
 813      */
 814     public final Spliterator<E> spliterator() {
 815         return new PriorityQueueSpliterator(0, -1, 0);
 816     }
 817 
 818     final class PriorityQueueSpliterator implements Spliterator<E> {
 819         private int index;            // current index, modified on advance/split
 820         private int fence;            // -1 until first use
 821         private int expectedModCount; // initialized when fence set
 822 
 823         /** Creates new spliterator covering the given range. */
 824         PriorityQueueSpliterator(int origin, int fence, int expectedModCount) {
 825             this.index = origin;
 826             this.fence = fence;
 827             this.expectedModCount = expectedModCount;
 828         }
 829 
 830         private int getFence() { // initialize fence to size on first use
 831             int hi;
 832             if ((hi = fence) < 0) {
 833                 expectedModCount = modCount;
 834                 hi = fence = size;
 835             }
 836             return hi;
 837         }
 838 
 839         public PriorityQueueSpliterator trySplit() {
 840             int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
 841             return (lo >= mid) ? null :
 842                 new PriorityQueueSpliterator(lo, index = mid, expectedModCount);
 843         }
 844 
 845         public void forEachRemaining(Consumer<? super E> action) {
 846             if (action == null)
 847                 throw new NullPointerException();
 848             if (fence < 0) { fence = size; expectedModCount = modCount; }
 849             final Object[] es = queue;
 850             int i, hi; E e;
 851             for (i = index, index = hi = fence; i < hi; i++) {
 852                 if ((e = (E) es[i]) == null)
 853                     break;      // must be CME
 854                 action.accept(e);
 855             }
 856             if (modCount != expectedModCount)
 857                 throw new ConcurrentModificationException();
 858         }
 859 
 860         public boolean tryAdvance(Consumer<? super E> action) {
 861             if (action == null)
 862                 throw new NullPointerException();
 863             if (fence < 0) { fence = size; expectedModCount = modCount; }
 864             int i;
 865             if ((i = index) < fence) {
 866                 index = i + 1;
 867                 E e;
 868                 if ((e = (E) queue[i]) == null
 869                     || modCount != expectedModCount)
 870                     throw new ConcurrentModificationException();
 871                 action.accept(e);
 872                 return true;
 873             }
 874             return false;
 875         }
 876 
 877         public long estimateSize() {
 878             return getFence() - index;
 879         }
 880 
 881         public int characteristics() {
 882             return Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.NONNULL;
 883         }
 884     }
 885 
 886     /**
 887      * @throws NullPointerException {@inheritDoc}
 888      */
 889     public boolean removeIf(Predicate<? super E> filter) {
 890         Objects.requireNonNull(filter);
 891         return bulkRemove(filter);
 892     }
 893 
 894     /**
 895      * @throws NullPointerException {@inheritDoc}
 896      */
 897     public boolean removeAll(Collection<?> c) {
 898         Objects.requireNonNull(c);
 899         return bulkRemove(e -> c.contains(e));
 900     }
 901 
 902     /**
 903      * @throws NullPointerException {@inheritDoc}
 904      */
 905     public boolean retainAll(Collection<?> c) {
 906         Objects.requireNonNull(c);
 907         return bulkRemove(e -> !c.contains(e));
 908     }
 909 
 910     // A tiny bit set implementation
 911 
 912     private static long[] nBits(int n) {
 913         return new long[((n - 1) >> 6) + 1];
 914     }
 915     private static void setBit(long[] bits, int i) {
 916         bits[i >> 6] |= 1L << i;
 917     }
 918     private static boolean isClear(long[] bits, int i) {
 919         return (bits[i >> 6] & (1L << i)) == 0;
 920     }
 921 
 922     /** Implementation of bulk remove methods. */
 923     private boolean bulkRemove(Predicate<? super E> filter) {
 924         final int expectedModCount = ++modCount;
 925         final Object[] es = queue;
 926         final int end = size;
 927         int i;
 928         // Optimize for initial run of survivors
 929         for (i = 0; i < end && !filter.test((E) es[i]); i++)
 930             ;
 931         if (i >= end) {
 932             if (modCount != expectedModCount)
 933                 throw new ConcurrentModificationException();
 934             return false;
 935         }
 936         // Tolerate predicates that reentrantly access the collection for
 937         // read (but writers still get CME), so traverse once to find
 938         // elements to delete, a second pass to physically expunge.
 939         final int beg = i;
 940         final long[] deathRow = nBits(end - beg);
 941         deathRow[0] = 1L;   // set bit 0
 942         for (i = beg + 1; i < end; i++)
 943             if (filter.test((E) es[i]))
 944                 setBit(deathRow, i - beg);
 945         if (modCount != expectedModCount)
 946             throw new ConcurrentModificationException();
 947         int w = beg;
 948         for (i = beg; i < end; i++)
 949             if (isClear(deathRow, i - beg))
 950                 es[w++] = es[i];
 951         for (i = size = w; i < end; i++)
 952             es[i] = null;
 953         heapify();
 954         return true;
 955     }
 956 
 957     /**
 958      * @throws NullPointerException {@inheritDoc}
 959      */
 960     public void forEach(Consumer<? super E> action) {
 961         Objects.requireNonNull(action);
 962         final int expectedModCount = modCount;
 963         final Object[] es = queue;
 964         for (int i = 0, n = size; i < n; i++)
 965             action.accept((E) es[i]);
 966         if (expectedModCount != modCount)
 967             throw new ConcurrentModificationException();
 968     }
 969 }