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