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