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