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