• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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    */
create()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    */
create( Iterable<? extends E> initialContents)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    */
orderedBy(Comparator<B> comparator)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    */
expectedSize(int expectedSize)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    */
maximumSize(int maximumSize)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 
Builder(Comparator<B> comparator)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      */
expectedSize(int expectedSize)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      */
maximumSize(int maximumSize)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      */
create()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      */
create( Iterable<? extends T> initialContents)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"
ordering()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 
MinMaxPriorityQueue(Builder<? super E> builder, int queueSize)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 
size()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    */
add(E element)250   @Override public boolean add(E element) {
251     offer(element);
252     return true;
253   }
254 
addAll(Collection<? extends E> newElements)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    */
offer(E element)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 
poll()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
elementData(int index)288   E elementData(int index) {
289     return (E) queue[index];
290   }
291 
peek()292   @Override public E peek() {
293     return isEmpty() ? null : elementData(0);
294   }
295 
296   /**
297    * Returns the index of the max element.
298    */
getMaxElementIndex()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    */
pollFirst()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    */
removeFirst()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    */
peekFirst()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    */
pollLast()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    */
removeLast()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    */
peekLast()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    */
removeAt(int index)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 
fillHole(int index, E toTrickle)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 
MoveDesc(E toTrickle, E replaced)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    */
removeAndGet(int index)447   private E removeAndGet(int index) {
448     E value = elementData(index);
449     removeAt(index);
450     return value;
451   }
452 
heapForIndex(int i)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 
isEvenLevel(int index)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    */
isIntact()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 
Heap(Ordering<E> ordering)491     Heap(Ordering<E> ordering) {
492       this.ordering = ordering;
493     }
494 
compareElements(int a, int b)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      */
tryCrossOverAndBubbleUp( int removeIndex, int vacated, E toTrickle)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      */
bubbleUp(int index, E x)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      */
bubbleUpAlternatingLevels(int index, E x)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      */
findMin(int index, int len)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      */
findMinChild(int index)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      */
findMinGrandChild(int index)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      */
crossOverUp(int index, E x)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      */
getCorrectLastElement(E actualLastElement)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      */
crossOver(int index, E x)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      */
fillHoleAt(int index)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 
verifyIndex(int i)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 
getLeftChildIndex(int i)724     private int getLeftChildIndex(int i) {
725       return i * 2 + 1;
726     }
727 
getRightChildIndex(int i)728     private int getRightChildIndex(int i) {
729       return i * 2 + 2;
730     }
731 
getParentIndex(int i)732     private int getParentIndex(int i) {
733       return (i - 1) / 2;
734     }
735 
getGrandparentIndex(int i)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 
hasNext()756     @Override public boolean hasNext() {
757       checkModCount();
758       return (nextNotInSkipMe(cursor + 1) < size())
759           || ((forgetMeNot != null) && !forgetMeNot.isEmpty());
760     }
761 
next()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 
remove()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()
containsExact(Iterable<E> elements, E target)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()
removeExact(Object target)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 
checkModCount()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      */
nextNotInSkipMe(int c)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    */
iterator()867   @Override public Iterator<E> iterator() {
868     return new QueueIterator();
869   }
870 
clear()871   @Override public void clear() {
872     for (int i = 0; i < size; i++) {
873       queue[i] = null;
874     }
875     size = 0;
876   }
877 
toArray()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    */
comparator()889   public Comparator<? super E> comparator() {
890     return minHeap.ordering;
891   }
892 
capacity()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 
initialQueueSize(int configuredExpectedSize, int maximumSize, Iterable<?> initialContents)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 
growIfNeeded()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. */
calculateNewCapacity()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 */
capAtMaximumSize(int queueSize, int maximumSize)937   private static int capAtMaximumSize(int queueSize, int maximumSize) {
938     return Math.min(queueSize - 1, maximumSize) + 1; // don't overflow
939   }
940 }
941