com.carrotsearch.hppcrt.heaps.ObjectHeapPriorityQueue Maven / Gradle / Ivy
Show all versions of hppcrt Show documentation
package com.carrotsearch.hppcrt.heaps;
import java.util.*;
import com.carrotsearch.hppcrt.*;
import com.carrotsearch.hppcrt.cursors.*;
import com.carrotsearch.hppcrt.predicates.*;
import com.carrotsearch.hppcrt.procedures.*;
import com.carrotsearch.hppcrt.strategies.*;
/**
* A Heap-based, min-priority queue of KType
s.
* i.e. top() is the smallest element,
* as defined by Sedgewick: Algorithms 4th Edition (2011).
* It assure O(log(N)) complexity for insertion, deletion and update priority of the min element,
* and constant time to examine the min element by {@link #top()}.
* Important:
* Ordering of elements must be defined either
* * by {@link Comparable}
* * or by a custom comparator provided in constructors,
* see {@link #comparator()} .
* @author Vincent Sonnier
*/
@javax.annotation.Generated(date = "2015-02-27T19:21:03+0100", value = "HPPC-RT generated from: ObjectHeapPriorityQueue.java")
public class ObjectHeapPriorityQueue extends AbstractObjectCollection
implements ObjectPriorityQueue, Cloneable
{
/**
* Default capacity if no other capacity is given in the constructor.
*/
public final static int DEFAULT_CAPACITY = 16;
/**
* Internal array for storing the priority queue.
* Important!
* The actual value in this field is always an instance of Object[]
.
* Be warned that javac
emits additional casts when buffer
* is directly accessed; these casts
* may result in exceptions at runtime. A workaround is to cast directly to
* Object[]
before accessing the buffer's elements (although it is highly
* recommended to use a {@link #iterator()} instead.
*
* * Direct priority queue iteration: iterate buffer[i] for i in [1; size()] (included) but is out-of-order w.r.t {@link #popTop()} *
*/ public KType[] buffer; /** * Number of elements in the queue. */ protected int elementsCount; /** * Defines the Comparator ordering of the queue, * If null, natural ordering is used. */ protected Comparator super KType> comparator; /** * Buffer resizing strategy. */ protected final ArraySizingStrategy resizer; /** * internal pool of ValueIterator (must be created in constructor) */ protected final IteratorPoolNote : The comparison criteria for
* identity test is based on
* * {@link Comparable} compareTo() if no
* * custom comparator is given, else it uses the {@link #comparator()} criteria.
*/
@Override
public int removeAllOccurrences(final KType e1)
{
this.currentOccurenceToBeRemoved = e1;
return removeAll(this.removeAllOccurencesPredicate);
}
/**
* {@inheritDoc}
*/
@Override
public int removeAll(final ObjectPredicate super KType> predicate)
{
//remove by position
int deleted = 0;
final KType[] buffer = this.buffer;
int elementsCount = this.elementsCount;
//1-based index
int pos = 1;
try
{
while (pos <= elementsCount)
{
//delete it
if (predicate.apply(buffer[pos]))
{
//put the last element at position pos, like in deleteIndex()
buffer[pos] = buffer[elementsCount];
//for GC
buffer[elementsCount] = (null);
//Diminish size
elementsCount--;
deleted++;
} //end if to delete
else
{
pos++;
}
} //end while
}
finally
{
this.elementsCount = elementsCount;
//reestablish heap
updatePriorities();
}
return deleted;
}
/**
* {@inheritDoc}
*/
@Override
public void clear()
{
//1-based indexing
ObjectArrays.blankArray(this.buffer, 1, this.elementsCount + 1);
this.elementsCount = 0;
}
/**
* An iterator implementation for {@link HeapPriorityQueue#iterator}.
* Holds a ObjectCursor Note : The comparison criteria for
* identity test is based on
* * {@link Comparable} compareTo() if no
* * custom comparator is given, else it uses the {@link #comparator()} criteria.
*/
@Override
public boolean contains(final KType element)
{
//1-based index
final int size = this.elementsCount;
final KType[] buff = this.buffer;
if (this.comparator == null) {
for (int i = 1; i <= size; i++)
{
if ((((Comparable super KType>) element).compareTo(buff[i]) == 0))
{
return true;
}
} //end for
}
else {
final Comparator super KType> comp = this.comparator;
for (int i = 1; i <= size; i++)
{
if (comp.compare(element, buff[i]) == 0)
{
return true;
}
} //end for
}
return false;
}
/**
* {@inheritDoc}
*/
@Override
public int size()
{
return this.elementsCount;
}
/**
* {@inheritDoc}
*/
@Override
public int capacity() {
return this.buffer.length - 1;
}
/**
* {@inheritDoc}
*/
@Override
public
* (both don't have set comparators)
* or
* (both have equal comparators defined by {@link #comparator}.equals(obj.comparator))
* then, both heaps are compared as follows:
* {@inheritDoc}
*/
@Override
/* */
@SuppressWarnings("unchecked")
/* */
public boolean equals(final Object obj)
{
if (obj != null)
{
if (obj == this) {
return true;
}
//we can only compare both ObjectHeapPriorityQueue,
//that has the same comparison function reference
if (obj instanceof ObjectHeapPriorityQueue>)
{
final ObjectHeapPriorityQueueexpectedAdditions
. Increases internal buffer size if needed.
*/
protected void ensureBufferSpace(final int expectedAdditions)
{
final int bufferLen = (this.buffer == null ? 0 : this.buffer.length - 1);
if (this.elementsCount > bufferLen - expectedAdditions)
{
final int newSize = this.resizer.grow(bufferLen, this.elementsCount, expectedAdditions + 1);
assert newSize >= this.elementsCount + expectedAdditions : "Resizer failed to" +
" return sensible new size: " + newSize + " <= "
+ (this.elementsCount + expectedAdditions);
final KType[] newBuffer = (Internals.KType
s is used instead
* , which means objects in this case must be {@link Comparable}.
* */
public Comparator super KType>
comparator() {
return this.comparator;
}
/**
* Sink function for Comparable elements
* @param k
*/
private void sinkComparable(int k)
{
final int N = this.elementsCount;
final KType[] buffer = this.buffer;
KType tmp;
int child;
while ((k << 1) <= N)
{
//get the child of k
child = k << 1;
if (child < N && (((Comparable super KType>) buffer[child]).compareTo(buffer[child + 1]) > 0))
{
child++;
}
if (!(((Comparable super KType>) buffer[k]).compareTo(buffer[child]) > 0))
{
break;
}
//swap k and child
tmp = buffer[k];
buffer[k] = buffer[child];
buffer[child] = tmp;
k = child;
} //end while
}
/**
* Sink function for ObjectComparator elements
* @param k
*/
private void sinkComparator(int k)
{
final int N = this.elementsCount;
final KType[] buffer = this.buffer;
KType tmp;
int child;
final Comparator super KType> comp = this.comparator;
while ((k << 1) <= N)
{
//get the child of k
child = k << 1;
if (child < N && comp.compare(buffer[child], buffer[child + 1]) > 0)
{
child++;
}
if (comp.compare(buffer[k], buffer[child]) <= 0)
{
break;
}
//swap k and child
tmp = buffer[k];
buffer[k] = buffer[child];
buffer[child] = tmp;
k = child;
} //end while
}
/**
* Swim function for Comparable elements
* @param k
*/
private void swimComparable(int k)
{
KType tmp;
int parent;
final KType[] buffer = this.buffer;
while (k > 1 && (((Comparable super KType>) buffer[k >> 1]).compareTo(buffer[k]) > 0))
{
//swap k and its parent
parent = k >> 1;
tmp = buffer[k];
buffer[k] = buffer[parent];
buffer[parent] = tmp;
k = parent;
}
}
/**
* Swim function for Comparator elements
* @param k
*/
private void swimComparator(int k)
{
KType tmp;
int parent;
final KType[] buffer = this.buffer;
final Comparator super KType> comp = this.comparator;
while (k > 1 && comp.compare(buffer[k >> 1], buffer[k]) > 0)
{
//swap k and its parent
parent = k >> 1;
tmp = buffer[k];
buffer[k] = buffer[parent];
buffer[parent] = tmp;
k = parent;
}
}
private void swim(final int k)
{
if (this.comparator == null)
{
swimComparable(k);
}
else
{
swimComparator(k);
}
}
private void sink(final int k)
{
if (this.comparator == null)
{
sinkComparable(k);
}
else
{
sinkComparator(k);
}
}
}