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