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
17package com.google.common.collect;
18
19import static com.google.common.base.Preconditions.checkArgument;
20import static com.google.common.base.Preconditions.checkNotNull;
21import static com.google.common.base.Preconditions.checkPositionIndex;
22import static com.google.common.base.Preconditions.checkState;
23
24import com.google.common.annotations.Beta;
25import com.google.common.annotations.VisibleForTesting;
26import com.google.common.math.IntMath;
27
28import java.util.AbstractQueue;
29import java.util.ArrayList;
30import java.util.Collection;
31import java.util.Collections;
32import java.util.Comparator;
33import java.util.ConcurrentModificationException;
34import java.util.Iterator;
35import java.util.LinkedList;
36import java.util.List;
37import java.util.NoSuchElementException;
38import java.util.PriorityQueue;
39import 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
90public 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