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