001/*
002 * Copyright (C) 2010 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package com.google.common.collect;
018
019import static com.google.common.base.Preconditions.checkArgument;
020import static com.google.common.base.Preconditions.checkNotNull;
021import static com.google.common.base.Preconditions.checkPositionIndex;
022import static com.google.common.base.Preconditions.checkState;
023import static com.google.common.collect.CollectPreconditions.checkRemove;
024import static java.lang.Math.max;
025import static java.lang.Math.min;
026import static java.lang.System.arraycopy;
027import static java.util.Objects.requireNonNull;
028
029import com.google.common.annotations.GwtCompatible;
030import com.google.common.annotations.J2ktIncompatible;
031import com.google.common.annotations.VisibleForTesting;
032import com.google.common.math.IntMath;
033import com.google.errorprone.annotations.CanIgnoreReturnValue;
034import com.google.j2objc.annotations.Weak;
035import com.google.j2objc.annotations.WeakOuter;
036import java.util.AbstractQueue;
037import java.util.ArrayDeque;
038import java.util.ArrayList;
039import java.util.Collection;
040import java.util.Collections;
041import java.util.Comparator;
042import java.util.ConcurrentModificationException;
043import java.util.Iterator;
044import java.util.List;
045import java.util.NoSuchElementException;
046import java.util.PriorityQueue;
047import java.util.Queue;
048import javax.annotation.CheckForNull;
049import org.checkerframework.checker.nullness.qual.Nullable;
050
051/**
052 * A double-ended priority queue, which provides constant-time access to both its least element and
053 * its greatest element, as determined by the queue's specified comparator. If no comparator is
054 * given at creation time, the natural order of elements is used. If no maximum size is given at
055 * creation time, the queue is unbounded.
056 *
057 * <p>Usage example:
058 *
059 * <pre>{@code
060 * MinMaxPriorityQueue<User> users = MinMaxPriorityQueue.orderedBy(userComparator)
061 *     .maximumSize(1000)
062 *     .create();
063 * }</pre>
064 *
065 * <p>As a {@link Queue} it functions exactly as a {@link PriorityQueue}: its head element -- the
066 * implicit target of the methods {@link #peek()}, {@link #poll()} and {@link #remove()} -- is
067 * defined as the <i>least</i> element in the queue according to the queue's comparator. But unlike
068 * a regular priority queue, the methods {@link #peekLast}, {@link #pollLast} and {@link
069 * #removeLast} are also provided, to act on the <i>greatest</i> element in the queue instead.
070 *
071 * <p>A min-max priority queue can be configured with a maximum size. If so, each time the size of
072 * the queue exceeds that value, the queue automatically removes its greatest element according to
073 * its comparator (which might be the element that was just added). This is different from
074 * conventional bounded queues, which either block or reject new elements when full.
075 *
076 * <p>This implementation is based on the <a
077 * href="http://portal.acm.org/citation.cfm?id=6621">min-max heap</a> developed by Atkinson, et al.
078 * Unlike many other double-ended priority queues, it stores elements in a single array, as compact
079 * as the traditional heap data structure used in {@link PriorityQueue}.
080 *
081 * <p>This class is not thread-safe, and does not accept null elements.
082 *
083 * <p><i>Performance notes:</i>
084 *
085 * <ul>
086 *   <li>If you only access one end of the queue, and do use a maximum size, this class will perform
087 *       significantly worse than a {@code PriorityQueue} with manual eviction above the maximum
088 *       size. In many cases {@link Ordering#leastOf} may work for your use case with significantly
089 *       improved (and asymptotically superior) performance.
090 *   <li>The retrieval operations {@link #peek}, {@link #peekFirst}, {@link #peekLast}, {@link
091 *       #element}, and {@link #size} are constant-time.
092 *   <li>The enqueuing and dequeuing operations ({@link #offer}, {@link #add}, and all the forms of
093 *       {@link #poll} and {@link #remove()}) run in {@code O(log n) time}.
094 *   <li>The {@link #remove(Object)} and {@link #contains} operations require linear ({@code O(n)})
095 *       time.
096 *   <li>If you only access one end of the queue, and don't use a maximum size, this class is
097 *       functionally equivalent to {@link PriorityQueue}, but significantly slower.
098 * </ul>
099 *
100 * @author Sverre Sundsdal
101 * @author Torbjorn Gannholm
102 * @since 8.0
103 */
104@GwtCompatible
105@ElementTypesAreNonnullByDefault
106public final class MinMaxPriorityQueue<E> extends AbstractQueue<E> {
107
108  /**
109   * Creates a new min-max priority queue with default settings: natural order, no maximum size, no
110   * initial contents, and an initial expected size of 11.
111   */
112  public static <E extends Comparable<E>> MinMaxPriorityQueue<E> create() {
113    return new Builder<Comparable<E>>(Ordering.natural()).create();
114  }
115
116  /**
117   * Creates a new min-max priority queue using natural order, no maximum size, and initially
118   * containing the given elements.
119   */
120  public static <E extends Comparable<E>> MinMaxPriorityQueue<E> create(
121      Iterable<? extends E> initialContents) {
122    return new Builder<E>(Ordering.<E>natural()).create(initialContents);
123  }
124
125  /**
126   * Creates and returns a new builder, configured to build {@code MinMaxPriorityQueue} instances
127   * that use {@code comparator} to determine the least and greatest elements.
128   */
129  /*
130   * TODO(cpovirk): Change to Comparator<? super B> to permit Comparator<@Nullable ...> and
131   * Comparator<SupertypeOfB>? What we have here matches the immutable collections, but those also
132   * expose a public Builder constructor that accepts "? super." So maybe we should do *that*
133   * instead.
134   */
135  public static <B> Builder<B> orderedBy(Comparator<B> comparator) {
136    return new Builder<>(comparator);
137  }
138
139  /**
140   * Creates and returns a new builder, configured to build {@code MinMaxPriorityQueue} instances
141   * sized appropriately to hold {@code expectedSize} elements.
142   */
143  @SuppressWarnings("rawtypes") // https://github.com/google/guava/issues/989
144  public static Builder<Comparable> expectedSize(int expectedSize) {
145    return new Builder<Comparable>(Ordering.natural()).expectedSize(expectedSize);
146  }
147
148  /**
149   * Creates and returns a new builder, configured to build {@code MinMaxPriorityQueue} instances
150   * that are limited to {@code maximumSize} elements. Each time a queue grows beyond this bound, it
151   * immediately removes its greatest element (according to its comparator), which might be the
152   * element that was just added.
153   */
154  @SuppressWarnings("rawtypes") // https://github.com/google/guava/issues/989
155  public static Builder<Comparable> maximumSize(int maximumSize) {
156    return new Builder<Comparable>(Ordering.natural()).maximumSize(maximumSize);
157  }
158
159  /**
160   * The builder class used in creation of min-max priority queues. Instead of constructing one
161   * directly, use {@link MinMaxPriorityQueue#orderedBy(Comparator)}, {@link
162   * MinMaxPriorityQueue#expectedSize(int)} or {@link MinMaxPriorityQueue#maximumSize(int)}.
163   *
164   * @param <B> the upper bound on the eventual type that can be produced by this builder (for
165   *     example, a {@code Builder<Number>} can produce a {@code Queue<Number>} or {@code
166   *     Queue<Integer>} but not a {@code Queue<Object>}).
167   * @since 8.0
168   */
169  public static final class Builder<B> {
170    /*
171     * TODO(kevinb): when the dust settles, see if we still need this or can
172     * just default to DEFAULT_CAPACITY.
173     */
174    private static final int UNSET_EXPECTED_SIZE = -1;
175
176    private final Comparator<B> comparator;
177    private int expectedSize = UNSET_EXPECTED_SIZE;
178    private int maximumSize = Integer.MAX_VALUE;
179
180    private Builder(Comparator<B> comparator) {
181      this.comparator = checkNotNull(comparator);
182    }
183
184    /**
185     * Configures this builder to build min-max priority queues with an initial expected size of
186     * {@code expectedSize}.
187     */
188    @CanIgnoreReturnValue
189    public Builder<B> expectedSize(int expectedSize) {
190      checkArgument(expectedSize >= 0);
191      this.expectedSize = expectedSize;
192      return this;
193    }
194
195    /**
196     * Configures this builder to build {@code MinMaxPriorityQueue} instances that are limited to
197     * {@code maximumSize} elements. Each time a queue grows beyond this bound, it immediately
198     * removes its greatest element (according to its comparator), which might be the element that
199     * was just added.
200     */
201    @CanIgnoreReturnValue
202    public Builder<B> maximumSize(int maximumSize) {
203      checkArgument(maximumSize > 0);
204      this.maximumSize = maximumSize;
205      return this;
206    }
207
208    /**
209     * Builds a new min-max priority queue using the previously specified options, and having no
210     * initial contents.
211     */
212    public <T extends B> MinMaxPriorityQueue<T> create() {
213      return create(Collections.<T>emptySet());
214    }
215
216    /**
217     * Builds a new min-max priority queue using the previously specified options, and having the
218     * given initial elements.
219     */
220    public <T extends B> MinMaxPriorityQueue<T> create(Iterable<? extends T> initialContents) {
221      MinMaxPriorityQueue<T> queue =
222          new MinMaxPriorityQueue<>(
223              this, initialQueueSize(expectedSize, maximumSize, initialContents));
224      for (T element : initialContents) {
225        queue.offer(element);
226      }
227      return queue;
228    }
229
230    @SuppressWarnings("unchecked") // safe "contravariant cast"
231    private <T extends B> Ordering<T> ordering() {
232      return Ordering.from((Comparator<T>) comparator);
233    }
234  }
235
236  private final Heap minHeap;
237  private final Heap maxHeap;
238  @VisibleForTesting final int maximumSize;
239  private @Nullable Object[] queue;
240  private int size;
241  private int modCount;
242
243  private MinMaxPriorityQueue(Builder<? super E> builder, int queueSize) {
244    Ordering<E> ordering = builder.ordering();
245    this.minHeap = new Heap(ordering);
246    this.maxHeap = new Heap(ordering.reverse());
247    minHeap.otherHeap = maxHeap;
248    maxHeap.otherHeap = minHeap;
249
250    this.maximumSize = builder.maximumSize;
251    // TODO(kevinb): pad?
252    this.queue = new Object[queueSize];
253  }
254
255  @Override
256  public int size() {
257    return size;
258  }
259
260  /**
261   * Adds the given element to this queue. If this queue has a maximum size, after adding {@code
262   * element} the queue will automatically evict its greatest element (according to its comparator),
263   * which may be {@code element} itself.
264   *
265   * @return {@code true} always
266   */
267  @CanIgnoreReturnValue
268  @Override
269  public boolean add(E element) {
270    offer(element);
271    return true;
272  }
273
274  @CanIgnoreReturnValue
275  @Override
276  public boolean addAll(Collection<? extends E> newElements) {
277    boolean modified = false;
278    for (E element : newElements) {
279      offer(element);
280      modified = true;
281    }
282    return modified;
283  }
284
285  /**
286   * Adds the given element to this queue. If this queue has a maximum size, after adding {@code
287   * element} the queue will automatically evict its greatest element (according to its comparator),
288   * which may be {@code element} itself.
289   */
290  @CanIgnoreReturnValue
291  @Override
292  public boolean offer(E element) {
293    checkNotNull(element);
294    modCount++;
295    int insertIndex = size++;
296
297    growIfNeeded();
298
299    // Adds the element to the end of the heap and bubbles it up to the correct
300    // position.
301    heapForIndex(insertIndex).bubbleUp(insertIndex, element);
302    return size <= maximumSize || pollLast() != element;
303  }
304
305  @CanIgnoreReturnValue
306  @Override
307  @CheckForNull
308  public E poll() {
309    return isEmpty() ? null : removeAndGet(0);
310  }
311
312  @SuppressWarnings("unchecked") // we must carefully only allow Es to get in
313  E elementData(int index) {
314    /*
315     * requireNonNull is safe as long as we're careful to call this method only with populated
316     * indexes.
317     */
318    return (E) requireNonNull(queue[index]);
319  }
320
321  @Override
322  @CheckForNull
323  public E peek() {
324    return isEmpty() ? null : elementData(0);
325  }
326
327  /** Returns the index of the max element. */
328  private int getMaxElementIndex() {
329    switch (size) {
330      case 1:
331        return 0; // The lone element in the queue is the maximum.
332      case 2:
333        return 1; // The lone element in the maxHeap is the maximum.
334      default:
335        // The max element must sit on the first level of the maxHeap. It is
336        // actually the *lesser* of the two from the maxHeap's perspective.
337        return (maxHeap.compareElements(1, 2) <= 0) ? 1 : 2;
338    }
339  }
340
341  /**
342   * Removes and returns the least element of this queue, or returns {@code null} if the queue is
343   * empty.
344   */
345  @CanIgnoreReturnValue
346  @CheckForNull
347  public E pollFirst() {
348    return poll();
349  }
350
351  /**
352   * Removes and returns the least element of this queue.
353   *
354   * @throws NoSuchElementException if the queue is empty
355   */
356  @CanIgnoreReturnValue
357  public E removeFirst() {
358    return remove();
359  }
360
361  /**
362   * Retrieves, but does not remove, the least element of this queue, or returns {@code null} if the
363   * queue is empty.
364   */
365  @CheckForNull
366  public E peekFirst() {
367    return peek();
368  }
369
370  /**
371   * Removes and returns the greatest element of this queue, or returns {@code null} if the queue is
372   * empty.
373   */
374  @CanIgnoreReturnValue
375  @CheckForNull
376  public E pollLast() {
377    return isEmpty() ? null : removeAndGet(getMaxElementIndex());
378  }
379
380  /**
381   * Removes and returns the greatest element of this queue.
382   *
383   * @throws NoSuchElementException if the queue is empty
384   */
385  @CanIgnoreReturnValue
386  public E removeLast() {
387    if (isEmpty()) {
388      throw new NoSuchElementException();
389    }
390    return removeAndGet(getMaxElementIndex());
391  }
392
393  /**
394   * Retrieves, but does not remove, the greatest element of this queue, or returns {@code null} if
395   * the queue is empty.
396   */
397  @CheckForNull
398  public E peekLast() {
399    return isEmpty() ? null : elementData(getMaxElementIndex());
400  }
401
402  /**
403   * Removes the element at position {@code index}.
404   *
405   * <p>Normally this method leaves the elements at up to {@code index - 1}, inclusive, untouched.
406   * Under these circumstances, it returns {@code null}.
407   *
408   * <p>Occasionally, in order to maintain the heap invariant, it must swap a later element of the
409   * list with one before {@code index}. Under these circumstances it returns a pair of elements as
410   * a {@link MoveDesc}. The first one is the element that was previously at the end of the heap and
411   * is now at some position before {@code index}. The second element is the one that was swapped
412   * down to replace the element at {@code index}. This fact is used by iterator.remove so as to
413   * visit elements during a traversal once and only once.
414   */
415  @VisibleForTesting
416  @CanIgnoreReturnValue
417  @CheckForNull
418  MoveDesc<E> removeAt(int index) {
419    checkPositionIndex(index, size);
420    modCount++;
421    size--;
422    if (size == index) {
423      queue[size] = null;
424      return null;
425    }
426    E actualLastElement = elementData(size);
427    int lastElementAt = heapForIndex(size).swapWithConceptuallyLastElement(actualLastElement);
428    if (lastElementAt == index) {
429      // 'actualLastElement' is now at 'lastElementAt', and the element that was at 'lastElementAt'
430      // is now at the end of queue. If that's the element we wanted to remove in the first place,
431      // don't try to (incorrectly) trickle it. Instead, just delete it and we're done.
432      queue[size] = null;
433      return null;
434    }
435    E toTrickle = elementData(size);
436    queue[size] = null;
437    MoveDesc<E> changes = fillHole(index, toTrickle);
438    if (lastElementAt < index) {
439      // Last element is moved to before index, swapped with trickled element.
440      if (changes == null) {
441        // The trickled element is still after index.
442        return new MoveDesc<>(actualLastElement, toTrickle);
443      } else {
444        // The trickled element is back before index, but the replaced element
445        // has now been moved after index.
446        return new MoveDesc<>(actualLastElement, changes.replaced);
447      }
448    }
449    // Trickled element was after index to begin with, no adjustment needed.
450    return changes;
451  }
452
453  @CheckForNull
454  private MoveDesc<E> fillHole(int index, E toTrickle) {
455    Heap heap = heapForIndex(index);
456    // We consider elementData(index) a "hole", and we want to fill it
457    // with the last element of the heap, toTrickle.
458    // Since the last element of the heap is from the bottom level, we
459    // optimistically fill index position with elements from lower levels,
460    // moving the hole down. In most cases this reduces the number of
461    // comparisons with toTrickle, but in some cases we will need to bubble it
462    // all the way up again.
463    int vacated = heap.fillHoleAt(index);
464    // Try to see if toTrickle can be bubbled up min levels.
465    int bubbledTo = heap.bubbleUpAlternatingLevels(vacated, toTrickle);
466    if (bubbledTo == vacated) {
467      // Could not bubble toTrickle up min levels, try moving
468      // it from min level to max level (or max to min level) and bubble up
469      // there.
470      return heap.tryCrossOverAndBubbleUp(index, vacated, toTrickle);
471    } else {
472      return (bubbledTo < index) ? new MoveDesc<E>(toTrickle, elementData(index)) : null;
473    }
474  }
475
476  // Returned from removeAt() to iterator.remove()
477  static class MoveDesc<E> {
478    final E toTrickle;
479    final E replaced;
480
481    MoveDesc(E toTrickle, E replaced) {
482      this.toTrickle = toTrickle;
483      this.replaced = replaced;
484    }
485  }
486
487  /** Removes and returns the value at {@code index}. */
488  private E removeAndGet(int index) {
489    E value = elementData(index);
490    removeAt(index);
491    return value;
492  }
493
494  private Heap heapForIndex(int i) {
495    return isEvenLevel(i) ? minHeap : maxHeap;
496  }
497
498  private static final int EVEN_POWERS_OF_TWO = 0x55555555;
499  private static final int ODD_POWERS_OF_TWO = 0xaaaaaaaa;
500
501  @VisibleForTesting
502  static boolean isEvenLevel(int index) {
503    int oneBased = ~~(index + 1); // for GWT
504    checkState(oneBased > 0, "negative index");
505    return (oneBased & EVEN_POWERS_OF_TWO) > (oneBased & ODD_POWERS_OF_TWO);
506  }
507
508  /**
509   * Returns {@code true} if the MinMax heap structure holds. This is only used in testing.
510   *
511   * <p>TODO(kevinb): move to the test class?
512   */
513  @VisibleForTesting
514  boolean isIntact() {
515    for (int i = 1; i < size; i++) {
516      if (!heapForIndex(i).verifyIndex(i)) {
517        return false;
518      }
519    }
520    return true;
521  }
522
523  /**
524   * Each instance of MinMaxPriorityQueue encapsulates two instances of Heap: a min-heap and a
525   * max-heap. Conceptually, these might each have their own array for storage, but for efficiency's
526   * sake they are stored interleaved on alternate heap levels in the same array (MMPQ.queue).
527   */
528  @WeakOuter
529  class Heap {
530    final Ordering<E> ordering;
531
532    @SuppressWarnings("nullness:initialization.field.uninitialized")
533    @Weak
534    Heap otherHeap; // always initialized immediately after construction
535
536    Heap(Ordering<E> ordering) {
537      this.ordering = ordering;
538    }
539
540    int compareElements(int a, int b) {
541      return ordering.compare(elementData(a), elementData(b));
542    }
543
544    /**
545     * Tries to move {@code toTrickle} from a min to a max level and bubble up there. If it moved
546     * before {@code removeIndex} this method returns a pair as described in {@link #removeAt}.
547     */
548    @CheckForNull
549    MoveDesc<E> tryCrossOverAndBubbleUp(int removeIndex, int vacated, E toTrickle) {
550      int crossOver = crossOver(vacated, toTrickle);
551      if (crossOver == vacated) {
552        return null;
553      }
554      // Successfully crossed over from min to max.
555      // Bubble up max levels.
556      E parent;
557      // If toTrickle is moved up to a parent of removeIndex, the parent is
558      // placed in removeIndex position. We must return that to the iterator so
559      // that it knows to skip it.
560      if (crossOver < removeIndex) {
561        // We crossed over to the parent level in crossOver, so the parent
562        // has already been moved.
563        parent = elementData(removeIndex);
564      } else {
565        parent = elementData(getParentIndex(removeIndex));
566      }
567      // bubble it up the opposite heap
568      if (otherHeap.bubbleUpAlternatingLevels(crossOver, toTrickle) < removeIndex) {
569        return new MoveDesc<>(toTrickle, parent);
570      } else {
571        return null;
572      }
573    }
574
575    /** Bubbles a value from {@code index} up the appropriate heap if required. */
576    void bubbleUp(int index, E x) {
577      int crossOver = crossOverUp(index, x);
578
579      Heap heap;
580      if (crossOver == index) {
581        heap = this;
582      } else {
583        index = crossOver;
584        heap = otherHeap;
585      }
586      heap.bubbleUpAlternatingLevels(index, x);
587    }
588
589    /**
590     * Bubbles a value from {@code index} up the levels of this heap, and returns the index the
591     * element ended up at.
592     */
593    @CanIgnoreReturnValue
594    int bubbleUpAlternatingLevels(int index, E x) {
595      while (index > 2) {
596        int grandParentIndex = getGrandparentIndex(index);
597        E e = elementData(grandParentIndex);
598        if (ordering.compare(e, x) <= 0) {
599          break;
600        }
601        queue[index] = e;
602        index = grandParentIndex;
603      }
604      queue[index] = x;
605      return index;
606    }
607
608    /**
609     * Returns the index of minimum value between {@code index} and {@code index + len}, or {@code
610     * -1} if {@code index} is greater than {@code size}.
611     */
612    int findMin(int index, int len) {
613      if (index >= size) {
614        return -1;
615      }
616      checkState(index > 0);
617      int limit = min(index, size - len) + len;
618      int minIndex = index;
619      for (int i = index + 1; i < limit; i++) {
620        if (compareElements(i, minIndex) < 0) {
621          minIndex = i;
622        }
623      }
624      return minIndex;
625    }
626
627    /** Returns the minimum child or {@code -1} if no child exists. */
628    int findMinChild(int index) {
629      return findMin(getLeftChildIndex(index), 2);
630    }
631
632    /** Returns the minimum grand child or -1 if no grand child exists. */
633    int findMinGrandChild(int index) {
634      int leftChildIndex = getLeftChildIndex(index);
635      if (leftChildIndex < 0) {
636        return -1;
637      }
638      return findMin(getLeftChildIndex(leftChildIndex), 4);
639    }
640
641    /**
642     * Moves an element one level up from a min level to a max level (or vice versa). Returns the
643     * new position of the element.
644     */
645    int crossOverUp(int index, E x) {
646      if (index == 0) {
647        queue[0] = x;
648        return 0;
649      }
650      int parentIndex = getParentIndex(index);
651      E parentElement = elementData(parentIndex);
652      if (parentIndex != 0) {
653        /*
654         * This is a guard for the case of the childless aunt node. Since the end of the array is
655         * actually the middle of the heap, a smaller childless aunt node can become a child of x
656         * when we bubble up alternate levels, violating the invariant.
657         */
658        int grandparentIndex = getParentIndex(parentIndex);
659        int auntIndex = getRightChildIndex(grandparentIndex);
660        if (auntIndex != parentIndex && getLeftChildIndex(auntIndex) >= size) {
661          E auntElement = elementData(auntIndex);
662          if (ordering.compare(auntElement, parentElement) < 0) {
663            parentIndex = auntIndex;
664            parentElement = auntElement;
665          }
666        }
667      }
668      if (ordering.compare(parentElement, x) < 0) {
669        queue[index] = parentElement;
670        queue[parentIndex] = x;
671        return parentIndex;
672      }
673      queue[index] = x;
674      return index;
675    }
676
677    // About the term "aunt node": it's better to leave gender out of it, but for this the English
678    // language has nothing for us. Except for the whimsical neologism "pibling" (!) which we
679    // obviously could not expect to increase anyone's understanding of the code.
680
681    /**
682     * Swap {@code actualLastElement} with the conceptually correct last element of the heap.
683     * Returns the index that {@code actualLastElement} now resides in.
684     *
685     * <p>Since the last element of the array is actually in the middle of the sorted structure, a
686     * childless aunt node could be smaller, which would corrupt the invariant if this element
687     * becomes the new parent of the aunt node. In that case, we first switch the last element with
688     * its aunt node, before returning.
689     */
690    int swapWithConceptuallyLastElement(E actualLastElement) {
691      int parentIndex = getParentIndex(size);
692      if (parentIndex != 0) {
693        int grandparentIndex = getParentIndex(parentIndex);
694        int auntIndex = getRightChildIndex(grandparentIndex);
695        if (auntIndex != parentIndex && getLeftChildIndex(auntIndex) >= size) {
696          E auntElement = elementData(auntIndex);
697          if (ordering.compare(auntElement, actualLastElement) < 0) {
698            queue[auntIndex] = actualLastElement;
699            queue[size] = auntElement;
700            return auntIndex;
701          }
702        }
703      }
704      return size;
705    }
706
707    /**
708     * Crosses an element over to the opposite heap by moving it one level down (or up if there are
709     * no elements below it).
710     *
711     * <p>Returns the new position of the element.
712     */
713    int crossOver(int index, E x) {
714      int minChildIndex = findMinChild(index);
715      // TODO(kevinb): split the && into two if's and move crossOverUp so it's
716      // only called when there's no child.
717      if ((minChildIndex > 0) && (ordering.compare(elementData(minChildIndex), x) < 0)) {
718        queue[index] = elementData(minChildIndex);
719        queue[minChildIndex] = x;
720        return minChildIndex;
721      }
722      return crossOverUp(index, x);
723    }
724
725    /**
726     * Fills the hole at {@code index} by moving in the least of its grandchildren to this position,
727     * then recursively filling the new hole created.
728     *
729     * @return the position of the new hole (where the lowest grandchild moved from, that had no
730     *     grandchild to replace it)
731     */
732    int fillHoleAt(int index) {
733      int minGrandchildIndex;
734      while ((minGrandchildIndex = findMinGrandChild(index)) > 0) {
735        queue[index] = elementData(minGrandchildIndex);
736        index = minGrandchildIndex;
737      }
738      return index;
739    }
740
741    private boolean verifyIndex(int i) {
742      if ((getLeftChildIndex(i) < size) && (compareElements(i, getLeftChildIndex(i)) > 0)) {
743        return false;
744      }
745      if ((getRightChildIndex(i) < size) && (compareElements(i, getRightChildIndex(i)) > 0)) {
746        return false;
747      }
748      if ((i > 0) && (compareElements(i, getParentIndex(i)) > 0)) {
749        return false;
750      }
751      if ((i > 2) && (compareElements(getGrandparentIndex(i), i) > 0)) {
752        return false;
753      }
754      return true;
755    }
756
757    // These would be static if inner classes could have static members.
758
759    private int getLeftChildIndex(int i) {
760      return i * 2 + 1;
761    }
762
763    private int getRightChildIndex(int i) {
764      return i * 2 + 2;
765    }
766
767    private int getParentIndex(int i) {
768      return (i - 1) / 2;
769    }
770
771    private int getGrandparentIndex(int i) {
772      return getParentIndex(getParentIndex(i)); // (i - 3) / 4
773    }
774  }
775
776  /**
777   * Iterates the elements of the queue in no particular order.
778   *
779   * <p>If the underlying queue is modified during iteration an exception will be thrown.
780   */
781  private class QueueIterator implements Iterator<E> {
782    private int cursor = -1;
783    private int nextCursor = -1;
784    private int expectedModCount = modCount;
785    // The same element is not allowed in both forgetMeNot and skipMe, but duplicates are allowed in
786    // either of them, up to the same multiplicity as the queue.
787    @CheckForNull private Queue<E> forgetMeNot;
788    @CheckForNull private List<E> skipMe;
789    @CheckForNull private E lastFromForgetMeNot;
790    private boolean canRemove;
791
792    @Override
793    public boolean hasNext() {
794      checkModCount();
795      nextNotInSkipMe(cursor + 1);
796      return (nextCursor < size()) || ((forgetMeNot != null) && !forgetMeNot.isEmpty());
797    }
798
799    @Override
800    public E next() {
801      checkModCount();
802      nextNotInSkipMe(cursor + 1);
803      if (nextCursor < size()) {
804        cursor = nextCursor;
805        canRemove = true;
806        return elementData(cursor);
807      } else if (forgetMeNot != null) {
808        cursor = size();
809        lastFromForgetMeNot = forgetMeNot.poll();
810        if (lastFromForgetMeNot != null) {
811          canRemove = true;
812          return lastFromForgetMeNot;
813        }
814      }
815      throw new NoSuchElementException("iterator moved past last element in queue.");
816    }
817
818    @Override
819    public void remove() {
820      checkRemove(canRemove);
821      checkModCount();
822      canRemove = false;
823      expectedModCount++;
824      if (cursor < size()) {
825        MoveDesc<E> moved = removeAt(cursor);
826        if (moved != null) {
827          // Either both are null or neither is, but we check both to satisfy the nullness checker.
828          if (forgetMeNot == null || skipMe == null) {
829            forgetMeNot = new ArrayDeque<>();
830            skipMe = new ArrayList<>(3);
831          }
832          if (!foundAndRemovedExactReference(skipMe, moved.toTrickle)) {
833            forgetMeNot.add(moved.toTrickle);
834          }
835          if (!foundAndRemovedExactReference(forgetMeNot, moved.replaced)) {
836            skipMe.add(moved.replaced);
837          }
838        }
839        cursor--;
840        nextCursor--;
841      } else { // we must have set lastFromForgetMeNot in next()
842        checkState(removeExact(requireNonNull(lastFromForgetMeNot)));
843        lastFromForgetMeNot = null;
844      }
845    }
846
847    /** Returns true if an exact reference (==) was found and removed from the supplied iterable. */
848    private boolean foundAndRemovedExactReference(Iterable<E> elements, E target) {
849      for (Iterator<E> it = elements.iterator(); it.hasNext(); ) {
850        E element = it.next();
851        if (element == target) {
852          it.remove();
853          return true;
854        }
855      }
856      return false;
857    }
858
859    /** Removes only this exact instance, not others that are equals() */
860    private boolean removeExact(Object target) {
861      for (int i = 0; i < size; i++) {
862        if (queue[i] == target) {
863          removeAt(i);
864          return true;
865        }
866      }
867      return false;
868    }
869
870    private void checkModCount() {
871      if (modCount != expectedModCount) {
872        throw new ConcurrentModificationException();
873      }
874    }
875
876    /**
877     * Advances nextCursor to the index of the first element after {@code c} that is not in {@code
878     * skipMe} and returns {@code size()} if there is no such element.
879     */
880    private void nextNotInSkipMe(int c) {
881      if (nextCursor < c) {
882        if (skipMe != null) {
883          while (c < size() && foundAndRemovedExactReference(skipMe, elementData(c))) {
884            c++;
885          }
886        }
887        nextCursor = c;
888      }
889    }
890  }
891
892  /**
893   * Returns an iterator over the elements contained in this collection, <i>in no particular
894   * order</i>.
895   *
896   * <p>The iterator is <i>fail-fast</i>: If the MinMaxPriorityQueue is modified at any time after
897   * the iterator is created, in any way except through the iterator's own remove method, the
898   * iterator will generally throw a {@link ConcurrentModificationException}. Thus, in the face of
899   * concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary,
900   * non-deterministic behavior at an undetermined time in the future.
901   *
902   * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally
903   * speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent
904   * modification. Fail-fast iterators throw {@code ConcurrentModificationException} on a
905   * best-effort basis. Therefore, it would be wrong to write a program that depended on this
906   * exception for its correctness: <i>the fail-fast behavior of iterators should be used only to
907   * detect bugs.</i>
908   *
909   * @return an iterator over the elements contained in this collection
910   */
911  @Override
912  public Iterator<E> iterator() {
913    return new QueueIterator();
914  }
915
916  @Override
917  public void clear() {
918    for (int i = 0; i < size; i++) {
919      queue[i] = null;
920    }
921    size = 0;
922  }
923
924  @Override
925  @J2ktIncompatible // Incompatible return type change. Use inherited (unoptimized) implementation
926  public Object[] toArray() {
927    Object[] copyTo = new Object[size];
928    arraycopy(queue, 0, copyTo, 0, size);
929    return copyTo;
930  }
931
932  /**
933   * Returns the comparator used to order the elements in this queue. Obeys the general contract of
934   * {@link PriorityQueue#comparator}, but returns {@link Ordering#natural} instead of {@code null}
935   * to indicate natural ordering.
936   */
937  public Comparator<? super E> comparator() {
938    return minHeap.ordering;
939  }
940
941  @VisibleForTesting
942  int capacity() {
943    return queue.length;
944  }
945
946  // Size/capacity-related methods
947
948  private static final int DEFAULT_CAPACITY = 11;
949
950  @VisibleForTesting
951  static int initialQueueSize(
952      int configuredExpectedSize, int maximumSize, Iterable<?> initialContents) {
953    // Start with what they said, if they said it, otherwise DEFAULT_CAPACITY
954    int result =
955        (configuredExpectedSize == Builder.UNSET_EXPECTED_SIZE)
956            ? DEFAULT_CAPACITY
957            : configuredExpectedSize;
958
959    // Enlarge to contain initial contents
960    if (initialContents instanceof Collection) {
961      int initialSize = ((Collection<?>) initialContents).size();
962      result = max(result, initialSize);
963    }
964
965    // Now cap it at maxSize + 1
966    return capAtMaximumSize(result, maximumSize);
967  }
968
969  private void growIfNeeded() {
970    if (size > queue.length) {
971      int newCapacity = calculateNewCapacity();
972      Object[] newQueue = new Object[newCapacity];
973      arraycopy(queue, 0, newQueue, 0, queue.length);
974      queue = newQueue;
975    }
976  }
977
978  /** Returns ~2x the old capacity if small; ~1.5x otherwise. */
979  private int calculateNewCapacity() {
980    int oldCapacity = queue.length;
981    int newCapacity =
982        (oldCapacity < 64) ? (oldCapacity + 1) * 2 : IntMath.checkedMultiply(oldCapacity / 2, 3);
983    return capAtMaximumSize(newCapacity, maximumSize);
984  }
985
986  /** There's no reason for the queueSize to ever be more than maxSize + 1 */
987  private static int capAtMaximumSize(int queueSize, int maximumSize) {
988    return min(queueSize - 1, maximumSize) + 1; // don't overflow
989  }
990}