11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/* 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2010 The Guava Authors 31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); 51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * you may not use this file except in compliance with the License. 61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * You may obtain a copy of the License at 71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0 91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software 111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS, 121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the License for the specific language governing permissions and 141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License. 151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.collect; 181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkArgument; 201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkNotNull; 211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkPositionIndex; 221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkState; 231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.Beta; 251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.VisibleForTesting; 261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.math.IntMath; 271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.AbstractQueue; 291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.ArrayList; 301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collection; 311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collections; 321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Comparator; 331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.ConcurrentModificationException; 341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Iterator; 351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.LinkedList; 361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.List; 371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.NoSuchElementException; 381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.PriorityQueue; 391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Queue; 401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/** 421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * A double-ended priority queue, which provides constant-time access to both 431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * its least element and its greatest element, as determined by the queue's 441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * specified comparator. If no comparator is given at construction time, the 451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * natural order of elements is used. 461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>As a {@link Queue} it functions exactly as a {@link PriorityQueue}: its 481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * head element -- the implicit target of the methods {@link #peek()}, {@link 491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * #poll()} and {@link #remove()} -- is defined as the <i>least</i> element in 501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the queue according to the queue's comparator. But unlike a regular priority 511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * queue, the methods {@link #peekLast}, {@link #pollLast} and 521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link #removeLast} are also provided, to act on the <i>greatest</i> element 531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * in the queue instead. 541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>A min-max priority queue can be configured with a maximum size. If so, 561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * each time the size of the queue exceeds that value, the queue automatically 571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * removes its greatest element according to its comparator (which might be the 581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * element that was just added). This is different from conventional bounded 591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * queues, which either block or reject new elements when full. 601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>This implementation is based on the 621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <a href="http://portal.acm.org/citation.cfm?id=6621">min-max heap</a> 631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * developed by Atkinson, et al. Unlike many other double-ended priority queues, 641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * it stores elements in a single array, as compact as the traditional heap data 651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * structure used in {@link PriorityQueue}. 661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>This class is not thread-safe, and does not accept null elements. 681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><i>Performance notes:</i> 701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <ul> 721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>The retrieval operations {@link #peek}, {@link #peekFirst}, {@link 731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * #peekLast}, {@link #element}, and {@link #size} are constant-time 741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>The enqueing and dequeing operations ({@link #offer}, {@link #add}, and 751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * all the forms of {@link #poll} and {@link #remove()}) run in {@code 761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * O(log n) time} 771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>The {@link #remove(Object)} and {@link #contains} operations require 781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * linear ({@code O(n)}) time 791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>If you only access one end of the queue, and don't use a maximum size, 801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * this class is functionally equivalent to {@link PriorityQueue}, but 811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * significantly slower. 821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * </ul> 831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Sverre Sundsdal 851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Torbjorn Gannholm 861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 8.0 871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert// TODO(kevinb): @GwtCompatible 891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@Beta 901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic final class MinMaxPriorityQueue<E> extends AbstractQueue<E> { 911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates a new min-max priority queue with default settings: natural order, 941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * no maximum size, no initial contents, and an initial expected size of 11. 951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <E extends Comparable<E>> MinMaxPriorityQueue<E> create() { 971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new Builder<Comparable>(Ordering.natural()).create(); 981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates a new min-max priority queue using natural order, no maximum size, 1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * and initially containing the given elements. 1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <E extends Comparable<E>> MinMaxPriorityQueue<E> create( 1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterable<? extends E> initialContents) { 1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new Builder<E>(Ordering.<E>natural()).create(initialContents); 1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates and returns a new builder, configured to build {@code 1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * MinMaxPriorityQueue} instances that use {@code comparator} to determine the 1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * least and greatest elements. 1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <B> Builder<B> orderedBy(Comparator<B> comparator) { 1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new Builder<B>(comparator); 1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates and returns a new builder, configured to build {@code 1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * MinMaxPriorityQueue} instances sized appropriately to hold {@code 1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * expectedSize} elements. 1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static Builder<Comparable> expectedSize(int expectedSize) { 1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new Builder<Comparable>(Ordering.natural()) 1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .expectedSize(expectedSize); 1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates and returns a new builder, configured to build {@code 1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * MinMaxPriorityQueue} instances that are limited to {@code maximumSize} 1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * elements. Each time a queue grows beyond this bound, it immediately 1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * removes its greatest element (according to its comparator), which might be 1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the element that was just added. 1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static Builder<Comparable> maximumSize(int maximumSize) { 1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new Builder<Comparable>(Ordering.natural()) 1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .maximumSize(maximumSize); 1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * The builder class used in creation of min-max priority queues. Instead of 1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * constructing one directly, use {@link 1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * MinMaxPriorityQueue#orderedBy(Comparator)}, {@link 1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * MinMaxPriorityQueue#expectedSize(int)} or {@link 1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * MinMaxPriorityQueue#maximumSize(int)}. 1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param <B> the upper bound on the eventual type that can be produced by 1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * this builder (for example, a {@code Builder<Number>} can produce a 1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code Queue<Number>} or {@code Queue<Integer>} but not a {@code 1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Queue<Object>}). 1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 8.0 1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Beta 1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static final class Builder<B> { 1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /* 1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * TODO(kevinb): when the dust settles, see if we still need this or can 1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * just default to DEFAULT_CAPACITY. 1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final int UNSET_EXPECTED_SIZE = -1; 1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private final Comparator<B> comparator; 1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private int expectedSize = UNSET_EXPECTED_SIZE; 1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private int maximumSize = Integer.MAX_VALUE; 1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private Builder(Comparator<B> comparator) { 1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.comparator = checkNotNull(comparator); 1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Configures this builder to build min-max priority queues with an initial 1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * expected size of {@code expectedSize}. 1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Builder<B> expectedSize(int expectedSize) { 1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(expectedSize >= 0); 1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.expectedSize = expectedSize; 1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Configures this builder to build {@code MinMaxPriorityQueue} instances 1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * that are limited to {@code maximumSize} elements. Each time a queue grows 1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * beyond this bound, it immediately removes its greatest element (according 1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * to its comparator), which might be the element that was just added. 1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Builder<B> maximumSize(int maximumSize) { 1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(maximumSize > 0); 1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.maximumSize = maximumSize; 1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Builds a new min-max priority queue using the previously specified 1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * options, and having no initial contents. 1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public <T extends B> MinMaxPriorityQueue<T> create() { 1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return create(Collections.<T>emptySet()); 1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Builds a new min-max priority queue using the previously specified 2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * options, and having the given initial elements. 2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public <T extends B> MinMaxPriorityQueue<T> create( 2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterable<? extends T> initialContents) { 2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert MinMaxPriorityQueue<T> queue = new MinMaxPriorityQueue<T>( 2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this, initialQueueSize(expectedSize, maximumSize, initialContents)); 2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (T element : initialContents) { 2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert queue.offer(element); 2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return queue; 2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") // safe "contravariant cast" 2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private <T extends B> Ordering<T> ordering() { 2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Ordering.from((Comparator<T>) comparator); 2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private final Heap minHeap; 2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private final Heap maxHeap; 2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @VisibleForTesting final int maximumSize; 2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private Object[] queue; 2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private int size; 2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private int modCount; 2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private MinMaxPriorityQueue(Builder<? super E> builder, int queueSize) { 2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Ordering<E> ordering = builder.ordering(); 2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.minHeap = new Heap(ordering); 2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.maxHeap = new Heap(ordering.reverse()); 2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert minHeap.otherHeap = maxHeap; 2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert maxHeap.otherHeap = minHeap; 2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.maximumSize = builder.maximumSize; 2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // TODO(kevinb): pad? 2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.queue = new Object[queueSize]; 2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return size; 2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Adds the given element to this queue. If this queue has a maximum size, 2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * after adding {@code element} the queue will automatically evict its 2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * greatest element (according to its comparator), which may be {@code 2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * element} itself. 2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return {@code true} always 2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean add(E element) { 2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert offer(element); 2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean addAll(Collection<? extends E> newElements) { 2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean modified = false; 2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (E element : newElements) { 2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert offer(element); 2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert modified = true; 2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return modified; 2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Adds the given element to this queue. If this queue has a maximum size, 2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * after adding {@code element} the queue will automatically evict its 2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * greatest element (according to its comparator), which may be {@code 2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * element} itself. 2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean offer(E element) { 2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(element); 2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert modCount++; 2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int insertIndex = size++; 2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert growIfNeeded(); 2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Adds the element to the end of the heap and bubbles it up to the correct 2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // position. 2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert heapForIndex(insertIndex).bubbleUp(insertIndex, element); 2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return size <= maximumSize || pollLast() != element; 2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public E poll() { 2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return isEmpty() ? null : removeAndGet(0); 2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") // we must carefully only allow Es to get in 2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert E elementData(int index) { 2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (E) queue[index]; 2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public E peek() { 2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return isEmpty() ? null : elementData(0); 2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns the index of the max element. 2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private int getMaxElementIndex() { 3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert switch (size) { 3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert case 1: 3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 0; // The lone element in the queue is the maximum. 3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert case 2: 3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 1; // The lone element in the maxHeap is the maximum. 3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert default: 3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // The max element must sit on the first level of the maxHeap. It is 3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // actually the *lesser* of the two from the maxHeap's perspective. 3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (maxHeap.compareElements(1, 2) <= 0) ? 1 : 2; 3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Removes and returns the least element of this queue, or returns {@code 3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * null} if the queue is empty. 3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public E pollFirst() { 3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return poll(); 3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Removes and returns the least element of this queue. 3221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws NoSuchElementException if the queue is empty 3241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public E removeFirst() { 3261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return remove(); 3271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Retrieves, but does not remove, the least element of this queue, or returns 3311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code null} if the queue is empty. 3321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public E peekFirst() { 3341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return peek(); 3351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Removes and returns the greatest element of this queue, or returns {@code 3391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * null} if the queue is empty. 3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public E pollLast() { 3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return isEmpty() ? null : removeAndGet(getMaxElementIndex()); 3431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Removes and returns the greatest element of this queue. 3471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws NoSuchElementException if the queue is empty 3491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public E removeLast() { 3511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (isEmpty()) { 3521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new NoSuchElementException(); 3531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return removeAndGet(getMaxElementIndex()); 3551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Retrieves, but does not remove, the greatest element of this queue, or 3591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * returns {@code null} if the queue is empty. 3601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public E peekLast() { 3621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return isEmpty() ? null : elementData(getMaxElementIndex()); 3631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Removes the element at position {@code index}. 3671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Normally this method leaves the elements at up to {@code index - 1}, 3691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * inclusive, untouched. Under these circumstances, it returns {@code null}. 3701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Occasionally, in order to maintain the heap invariant, it must swap a 3721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * later element of the list with one before {@code index}. Under these 3731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * circumstances it returns a pair of elements as a {@link MoveDesc}. The 3741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * first one is the element that was previously at the end of the heap and is 3751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * now at some position before {@code index}. The second element is the one 3761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * that was swapped down to replace the element at {@code index}. This fact is 3771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * used by iterator.remove so as to visit elements during a traversal once and 3781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * only once. 3791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @VisibleForTesting MoveDesc<E> removeAt(int index) { 3811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkPositionIndex(index, size); 3821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert modCount++; 3831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert size--; 3841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (size == index) { 3851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert queue[size] = null; 3861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return null; 3871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert E actualLastElement = elementData(size); 3891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int lastElementAt = heapForIndex(size) 3901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .getCorrectLastElement(actualLastElement); 3911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert E toTrickle = elementData(size); 3921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert queue[size] = null; 3931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert MoveDesc<E> changes = fillHole(index, toTrickle); 3941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (lastElementAt < index) { 3951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Last element is moved to before index, swapped with trickled element. 3961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (changes == null) { 3971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // The trickled element is still after index. 3981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new MoveDesc<E>(actualLastElement, toTrickle); 3991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 4001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // The trickled element is back before index, but the replaced element 4011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // has now been moved after index. 4021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new MoveDesc<E>(actualLastElement, changes.replaced); 4031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Trickled element was after index to begin with, no adjustment needed. 4061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return changes; 4071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private MoveDesc<E> fillHole(int index, E toTrickle) { 4101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Heap heap = heapForIndex(index); 4111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // We consider elementData(index) a "hole", and we want to fill it 4121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // with the last element of the heap, toTrickle. 4131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Since the last element of the heap is from the bottom level, we 4141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // optimistically fill index position with elements from lower levels, 4151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // moving the hole down. In most cases this reduces the number of 4161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // comparisons with toTrickle, but in some cases we will need to bubble it 4171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // all the way up again. 4181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int vacated = heap.fillHoleAt(index); 4191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Try to see if toTrickle can be bubbled up min levels. 4201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int bubbledTo = heap.bubbleUpAlternatingLevels(vacated, toTrickle); 4211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (bubbledTo == vacated) { 4221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Could not bubble toTrickle up min levels, try moving 4231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // it from min level to max level (or max to min level) and bubble up 4241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // there. 4251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return heap.tryCrossOverAndBubbleUp(index, vacated, toTrickle); 4261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 4271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (bubbledTo < index) 4281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ? new MoveDesc<E>(toTrickle, elementData(index)) 4291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert : null; 4301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Returned from removeAt() to iterator.remove() 4341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static class MoveDesc<E> { 4351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final E toTrickle; 4361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final E replaced; 4371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert MoveDesc(E toTrickle, E replaced) { 4391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.toTrickle = toTrickle; 4401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.replaced = replaced; 4411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 4451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Removes and returns the value at {@code index}. 4461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 4471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private E removeAndGet(int index) { 4481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert E value = elementData(index); 4491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert removeAt(index); 4501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return value; 4511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private Heap heapForIndex(int i) { 4541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return isEvenLevel(i) ? minHeap : maxHeap; 4551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final int EVEN_POWERS_OF_TWO = 0x55555555; 4581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final int ODD_POWERS_OF_TWO = 0xaaaaaaaa; 4591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @VisibleForTesting static boolean isEvenLevel(int index) { 4611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int oneBased = index + 1; 4621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkState(oneBased > 0, "negative index"); 4631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (oneBased & EVEN_POWERS_OF_TWO) > (oneBased & ODD_POWERS_OF_TWO); 4641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 4671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns {@code true} if the MinMax heap structure holds. This is only used 4681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * in testing. 4691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * TODO(kevinb): move to the test class? 4711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 4721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @VisibleForTesting boolean isIntact() { 4731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 1; i < size; i++) { 4741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!heapForIndex(i).verifyIndex(i)) { 4751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 4761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 4791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 4821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Each instance of MinMaxPriortyQueue encapsulates two instances of Heap: 4831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * a min-heap and a max-heap. Conceptually, these might each have their own 4841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * array for storage, but for efficiency's sake they are stored interleaved on 4851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * alternate heap levels in the same array (MMPQ.queue). 4861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 4871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private class Heap { 4881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Ordering<E> ordering; 4891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Heap otherHeap; 4901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Heap(Ordering<E> ordering) { 4921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.ordering = ordering; 4931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int compareElements(int a, int b) { 4961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return ordering.compare(elementData(a), elementData(b)); 4971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 5001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Tries to move {@code toTrickle} from a min to a max level and 5011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * bubble up there. If it moved before {@code removeIndex} this method 5021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * returns a pair as described in {@link #removeAt}. 5031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 5041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert MoveDesc<E> tryCrossOverAndBubbleUp( 5051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int removeIndex, int vacated, E toTrickle) { 5061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int crossOver = crossOver(vacated, toTrickle); 5071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (crossOver == vacated) { 5081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return null; 5091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Successfully crossed over from min to max. 5111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Bubble up max levels. 5121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert E parent; 5131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // If toTrickle is moved up to a parent of removeIndex, the parent is 5141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // placed in removeIndex position. We must return that to the iterator so 5151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // that it knows to skip it. 5161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (crossOver < removeIndex) { 5171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // We crossed over to the parent level in crossOver, so the parent 5181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // has already been moved. 5191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert parent = elementData(removeIndex); 5201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 5211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert parent = elementData(getParentIndex(removeIndex)); 5221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // bubble it up the opposite heap 5241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (otherHeap.bubbleUpAlternatingLevels(crossOver, toTrickle) 5251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert < removeIndex) { 5261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new MoveDesc<E>(toTrickle, parent); 5271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 5281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return null; 5291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 5331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Bubbles a value from {@code index} up the appropriate heap if required. 5341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 5351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert void bubbleUp(int index, E x) { 5361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int crossOver = crossOverUp(index, x); 5371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Heap heap; 5391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (crossOver == index) { 5401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert heap = this; 5411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 5421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert index = crossOver; 5431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert heap = otherHeap; 5441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert heap.bubbleUpAlternatingLevels(index, x); 5461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 5491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Bubbles a value from {@code index} up the levels of this heap, and 5501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * returns the index the element ended up at. 5511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 5521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int bubbleUpAlternatingLevels(int index, E x) { 5531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (index > 2) { 5541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int grandParentIndex = getGrandparentIndex(index); 5551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert E e = elementData(grandParentIndex); 5561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (ordering.compare(e, x) <= 0) { 5571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert break; 5581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert queue[index] = e; 5601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert index = grandParentIndex; 5611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert queue[index] = x; 5631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return index; 5641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 5671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns the index of minimum value between {@code index} and 5681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code index + len}, or {@code -1} if {@code index} is greater than 5691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code size}. 5701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 5711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int findMin(int index, int len) { 5721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (index >= size) { 5731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return -1; 5741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkState(index > 0); 5761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int limit = Math.min(index, size - len) + len; 5771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int minIndex = index; 5781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = index + 1; i < limit; i++) { 5791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (compareElements(i, minIndex) < 0) { 5801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert minIndex = i; 5811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return minIndex; 5841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 5871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns the minimum child or {@code -1} if no child exists. 5881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 5891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int findMinChild(int index) { 5901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return findMin(getLeftChildIndex(index), 2); 5911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 5941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns the minimum grand child or -1 if no grand child exists. 5951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 5961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int findMinGrandChild(int index) { 5971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int leftChildIndex = getLeftChildIndex(index); 5981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (leftChildIndex < 0) { 5991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return -1; 6001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return findMin(getLeftChildIndex(leftChildIndex), 4); 6021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 6051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Moves an element one level up from a min level to a max level 6061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * (or vice versa). 6071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns the new position of the element. 6081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 6091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int crossOverUp(int index, E x) { 6101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (index == 0) { 6111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert queue[0] = x; 6121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 0; 6131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int parentIndex = getParentIndex(index); 6151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert E parentElement = elementData(parentIndex); 6161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (parentIndex != 0) { 6171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // This is a guard for the case of the childless uncle. 6181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Since the end of the array is actually the middle of the heap, 6191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // a smaller childless uncle can become a child of x when we 6201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // bubble up alternate levels, violating the invariant. 6211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int grandparentIndex = getParentIndex(parentIndex); 6221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int uncleIndex = getRightChildIndex(grandparentIndex); 6231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (uncleIndex != parentIndex 6241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert && getLeftChildIndex(uncleIndex) >= size) { 6251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert E uncleElement = elementData(uncleIndex); 6261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (ordering.compare(uncleElement, parentElement) < 0) { 6271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert parentIndex = uncleIndex; 6281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert parentElement = uncleElement; 6291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (ordering.compare(parentElement, x) < 0) { 6331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert queue[index] = parentElement; 6341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert queue[parentIndex] = x; 6351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return parentIndex; 6361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert queue[index] = x; 6381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return index; 6391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 6421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns the conceptually correct last element of the heap. 6431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 6441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Since the last element of the array is actually in the 6451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * middle of the sorted structure, a childless uncle node could be 6461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * smaller, which would corrupt the invariant if this element 6471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * becomes the new parent of the uncle. In that case, we first 6481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * switch the last element with its uncle, before returning. 6491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 6501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int getCorrectLastElement(E actualLastElement) { 6511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int parentIndex = getParentIndex(size); 6521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (parentIndex != 0) { 6531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int grandparentIndex = getParentIndex(parentIndex); 6541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int uncleIndex = getRightChildIndex(grandparentIndex); 6551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (uncleIndex != parentIndex 6561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert && getLeftChildIndex(uncleIndex) >= size) { 6571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert E uncleElement = elementData(uncleIndex); 6581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (ordering.compare(uncleElement, actualLastElement) < 0) { 6591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert queue[uncleIndex] = actualLastElement; 6601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert queue[size] = uncleElement; 6611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return uncleIndex; 6621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return size; 6661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 6691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Crosses an element over to the opposite heap by moving it one level down 6701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * (or up if there are no elements below it). 6711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 6721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns the new position of the element. 6731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 6741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int crossOver(int index, E x) { 6751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int minChildIndex = findMinChild(index); 6761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // TODO(kevinb): split the && into two if's and move crossOverUp so it's 6771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // only called when there's no child. 6781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if ((minChildIndex > 0) 6791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert && (ordering.compare(elementData(minChildIndex), x) < 0)) { 6801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert queue[index] = elementData(minChildIndex); 6811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert queue[minChildIndex] = x; 6821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return minChildIndex; 6831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return crossOverUp(index, x); 6851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 6881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Fills the hole at {@code index} by moving in the least of its 6891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * grandchildren to this position, then recursively filling the new hole 6901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * created. 6911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 6921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return the position of the new hole (where the lowest grandchild moved 6931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * from, that had no grandchild to replace it) 6941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 6951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int fillHoleAt(int index) { 6961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int minGrandchildIndex; 6971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while ((minGrandchildIndex = findMinGrandChild(index)) > 0) { 6981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert queue[index] = elementData(minGrandchildIndex); 6991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert index = minGrandchildIndex; 7001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return index; 7021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private boolean verifyIndex(int i) { 7051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if ((getLeftChildIndex(i) < size) 7061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert && (compareElements(i, getLeftChildIndex(i)) > 0)) { 7071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 7081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if ((getRightChildIndex(i) < size) 7101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert && (compareElements(i, getRightChildIndex(i)) > 0)) { 7111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 7121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if ((i > 0) && (compareElements(i, getParentIndex(i)) > 0)) { 7141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 7151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if ((i > 2) && (compareElements(getGrandparentIndex(i), i) > 0)) { 7171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 7181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 7201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // These would be static if inner classes could have static members. 7231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private int getLeftChildIndex(int i) { 7251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return i * 2 + 1; 7261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private int getRightChildIndex(int i) { 7291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return i * 2 + 2; 7301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private int getParentIndex(int i) { 7331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (i - 1) / 2; 7341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private int getGrandparentIndex(int i) { 7371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return getParentIndex(getParentIndex(i)); // (i - 3) / 4 7381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 7421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Iterates the elements of the queue in no particular order. 7431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * If the underlying queue is modified during iteration an exception will be 7451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * thrown. 7461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 7471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private class QueueIterator implements Iterator<E> { 7481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private int cursor = -1; 7491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private int expectedModCount = modCount; 7501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // TODO(user): Switch to ArrayDeque once Guava supports it. 7511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private Queue<E> forgetMeNot; 7521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private List<E> skipMe; 7531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private E lastFromForgetMeNot; 7541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private boolean canRemove; 7551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean hasNext() { 7571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkModCount(); 7581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (nextNotInSkipMe(cursor + 1) < size()) 7591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert || ((forgetMeNot != null) && !forgetMeNot.isEmpty()); 7601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public E next() { 7631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkModCount(); 7641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int tempCursor = nextNotInSkipMe(cursor + 1); 7651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (tempCursor < size()) { 7661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert cursor = tempCursor; 7671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert canRemove = true; 7681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return elementData(cursor); 7691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else if (forgetMeNot != null) { 7701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert cursor = size(); 7711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert lastFromForgetMeNot = forgetMeNot.poll(); 7721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (lastFromForgetMeNot != null) { 7731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert canRemove = true; 7741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return lastFromForgetMeNot; 7751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new NoSuchElementException( 7781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert "iterator moved past last element in queue."); 7791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void remove() { 7821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkState(canRemove, 7831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert "no calls to remove() since the last call to next()"); 7841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkModCount(); 7851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert canRemove = false; 7861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert expectedModCount++; 7871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (cursor < size()) { 7881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert MoveDesc<E> moved = removeAt(cursor); 7891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (moved != null) { 7901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (forgetMeNot == null) { 7911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert forgetMeNot = new LinkedList<E>(); 7921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert skipMe = new ArrayList<E>(3); 7931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert forgetMeNot.add(moved.toTrickle); 7951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert skipMe.add(moved.replaced); 7961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert cursor--; 7981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { // we must have set lastFromForgetMeNot in next() 7991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkState(removeExact(lastFromForgetMeNot)); 8001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert lastFromForgetMeNot = null; 8011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Finds only this exact instance, not others that are equals() 8051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private boolean containsExact(Iterable<E> elements, E target) { 8061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (E element : elements) { 8071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (element == target) { 8081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 8091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 8121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Removes only this exact instance, not others that are equals() 8151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean removeExact(Object target) { 8161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < size; i++) { 8171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (queue[i] == target) { 8181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert removeAt(i); 8191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 8201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 8231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert void checkModCount() { 8261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (modCount != expectedModCount) { 8271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new ConcurrentModificationException(); 8281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 8321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns the index of the first element after {@code c} that is not in 8331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code skipMe} and returns {@code size()} if there is no such element. 8341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 8351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private int nextNotInSkipMe(int c) { 8361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (skipMe != null) { 8371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (c < size() && containsExact(skipMe, elementData(c))) { 8381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert c++; 8391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return c; 8421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 8461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an iterator over the elements contained in this collection, 8471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <i>in no particular order</i>. 8481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 8491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The iterator is <i>fail-fast</i>: If the MinMaxPriorityQueue is modified 8501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * at any time after the iterator is created, in any way except through the 8511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * iterator's own remove method, the iterator will generally throw a 8521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link ConcurrentModificationException}. Thus, in the face of concurrent 8531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * modification, the iterator fails quickly and cleanly, rather than risking 8541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * arbitrary, non-deterministic behavior at an undetermined time in the 8551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * future. 8561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 8571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed 8581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * as it is, generally speaking, impossible to make any hard guarantees in the 8591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * presence of unsynchronized concurrent modification. Fail-fast iterators 8601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * throw {@code ConcurrentModificationException} on a best-effort basis. 8611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Therefore, it would be wrong to write a program that depended on this 8621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * exception for its correctness: <i>the fail-fast behavior of iterators 8631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * should be used only to detect bugs.</i> 8641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 8651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return an iterator over the elements contained in this collection 8661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 8671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<E> iterator() { 8681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new QueueIterator(); 8691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void clear() { 8721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < size; i++) { 8731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert queue[i] = null; 8741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert size = 0; 8761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Object[] toArray() { 8791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object[] copyTo = new Object[size]; 8801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert System.arraycopy(queue, 0, copyTo, 0, size); 8811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return copyTo; 8821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 8851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns the comparator used to order the elements in this queue. Obeys the 8861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * general contract of {@link PriorityQueue#comparator}, but returns {@link 8871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Ordering#natural} instead of {@code null} to indicate natural ordering. 8881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 8891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Comparator<? super E> comparator() { 8901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return minHeap.ordering; 8911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @VisibleForTesting int capacity() { 8941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return queue.length; 8951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Size/capacity-related methods 8981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final int DEFAULT_CAPACITY = 11; 9001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @VisibleForTesting static int initialQueueSize(int configuredExpectedSize, 9021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int maximumSize, Iterable<?> initialContents) { 9031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Start with what they said, if they said it, otherwise DEFAULT_CAPACITY 9041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int result = (configuredExpectedSize == Builder.UNSET_EXPECTED_SIZE) 9051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ? DEFAULT_CAPACITY 9061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert : configuredExpectedSize; 9071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Enlarge to contain initial contents 9091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (initialContents instanceof Collection) { 9101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int initialSize = ((Collection<?>) initialContents).size(); 9111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert result = Math.max(result, initialSize); 9121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Now cap it at maxSize + 1 9151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return capAtMaximumSize(result, maximumSize); 9161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private void growIfNeeded() { 9191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (size > queue.length) { 9201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int newCapacity = calculateNewCapacity(); 9211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object[] newQueue = new Object[newCapacity]; 9221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert System.arraycopy(queue, 0, newQueue, 0, queue.length); 9231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert queue = newQueue; 9241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** Returns ~2x the old capacity if small; ~1.5x otherwise. */ 9281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private int calculateNewCapacity() { 9291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int oldCapacity = queue.length; 9301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int newCapacity = (oldCapacity < 64) 9311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ? (oldCapacity + 1) * 2 9321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert : IntMath.checkedMultiply(oldCapacity / 2, 3); 9331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return capAtMaximumSize(newCapacity, maximumSize); 9341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** There's no reason for the queueSize to ever be more than maxSize + 1 */ 9371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static int capAtMaximumSize(int queueSize, int maximumSize) { 9381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Math.min(queueSize - 1, maximumSize) + 1; // don't overflow 9391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert} 941