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