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