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