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