com.carrotsearch.hppcrt.lists.IntArrayDeque Maven / Gradle / Ivy
Show all versions of hppcrt Show documentation
package com.carrotsearch.hppcrt.lists;
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.sorting.*;
/**
* An array-backed deque (double-ended queue) of ints. A single array is used to store and
* manipulate all elements. Reallocations are governed by a {@link ArraySizingStrategy}
* and may be expensive if they move around really large chunks of memory.
* This dequeue is also a IntIndexedContainer, where index 0 is the head of the queue, and
* size() - 1 index is the last element.
* See {@link ObjectArrayDeque} class for API similarities and differences against Java
* Collections.
*/
@javax.annotation.Generated(date = "2014-10-25T20:54:04+0200", value = "HPPC-RT generated from: IntArrayDeque.java")
public class IntArrayDeque
extends AbstractIntCollection implements IntDeque, IntIndexedContainer, Cloneable
{
/**
* Default capacity if no other capacity is given in the constructor.
*/
public final static int DEFAULT_CAPACITY = 5;
/**
* Internal array for storing elements.
*
*
* Direct deque iteration from head to tail: iterate buffer[i % buffer.length] for i in [this.head; this.head + size()[
*
*/
public int[] buffer;
/**
* The index of the element at the head of the deque or an
* arbitrary number equal to tail if the deque is empty.
*/
public int head;
/**
* The index at which the next element would be added to the tail
* of the deque.
*/
public int tail;
/**
* Buffer resizing strategy.
*/
protected final ArraySizingStrategy resizer;
/**
* internal pool of DescendingValueIterator (must be created in constructor)
*/
protected final IteratorPool descendingValueIteratorPool;
/**
* internal pool of ValueIterator (must be created in constructor)
*/
protected final IteratorPool valueIteratorPool;
/**
* Create with default sizing strategy and initial capacity for storing
* {@value #DEFAULT_CAPACITY} elements.
*
* @see BoundedProportionalArraySizingStrategy
*/
public IntArrayDeque()
{
this(IntArrayDeque.DEFAULT_CAPACITY);
}
/**
* Create with default sizing strategy and the given initial capacity.
*
* @see BoundedProportionalArraySizingStrategy
*/
public IntArrayDeque(final int initialCapacity)
{
this(initialCapacity, new BoundedProportionalArraySizingStrategy());
}
/**
* Create with a custom buffer resizing strategy.
*/
public IntArrayDeque(int initialCapacity, final ArraySizingStrategy resizer)
{
assert initialCapacity >= 0 : "initialCapacity must be >= 0: " + initialCapacity;
assert resizer != null;
this.resizer = resizer;
// +1 because there is always one empty slot in a deque. (seen ensure buffer space)
initialCapacity = resizer.round(initialCapacity + 1);
this.buffer = new int [initialCapacity];
this.valueIteratorPool = new IteratorPool(
new ObjectFactory() {
@Override
public ValueIterator create()
{
return new ValueIterator();
}
@Override
public void initialize(final ValueIterator obj)
{
obj.cursor.index = ((IntArrayDeque.this.head >= 1) ? IntArrayDeque.this.head - 1 : IntArrayDeque.this.buffer.length - 1);
obj.remaining = IntArrayDeque.this.size();
}
@Override
public void reset(final ValueIterator obj) {
// nothing
}
});
this.descendingValueIteratorPool = new IteratorPool(
new ObjectFactory() {
@Override
public DescendingValueIterator create()
{
return new DescendingValueIterator();
}
@Override
public void initialize(final DescendingValueIterator obj)
{
obj.cursor.index = IntArrayDeque.this.tail;
obj.remaining = IntArrayDeque.this.size();
}
@Override
public void reset(final DescendingValueIterator obj) {
// nothing
}
});
}
/**
* Creates a new deque from elements of another container, appending them
* at the end of this deque.
*/
public IntArrayDeque(final IntContainer container)
{
this(container.size());
addLast(container);
}
/**
* {@inheritDoc}
*/
@Override
public void addFirst(final int e1)
{
int h = ((this.head >= 1) ? this.head - 1 : this.buffer.length - 1);
if (h == this.tail)
{
ensureBufferSpace(1);
h = ((this.head >= 1) ? this.head - 1 : this.buffer.length - 1);
}
this.buffer[this.head = h] = e1;
}
/**
* Vararg-signature method for adding elements at the front of this deque.
*
* This method is handy, but costly if used in tight loops (anonymous
* array passing)
*/
public void addFirst(final int... elements)
{
ensureBufferSpace(elements.length);
// For now, naive loop.
for (int i = 0; i < elements.length; i++) {
addFirst(elements[i]);
}
}
/**
* Inserts all elements from the given container to the front of this deque.
*
* @return Returns the number of elements actually added as a result of this
* call.
*/
public int addFirst(final IntContainer container)
{
return addFirst((Iterable extends IntCursor>) container);
}
/**
* Inserts all elements from the given iterable to the front of this deque.
*
* @return Returns the number of elements actually added as a result of this call.
*/
public int addFirst(final Iterable extends IntCursor> iterable)
{
int size = 0;
for (final IntCursor cursor : iterable)
{
addFirst(cursor.value);
size++;
}
return size;
}
/**
* {@inheritDoc}
*/
@Override
public void addLast(final int e1)
{
int t = ((this.tail + 1 == this.buffer.length) ? 0 : this.tail + 1);
if (this.head == t)
{
ensureBufferSpace(1);
t = ((this.tail + 1 == this.buffer.length) ? 0 : this.tail + 1);
}
this.buffer[this.tail] = e1;
this.tail = t;
}
/**
* Vararg-signature method for adding elements at the end of this deque.
*
* This method is handy, but costly if used in tight loops (anonymous
* array passing)
*/
public void addLast(final int... elements)
{
ensureBufferSpace(1);
// For now, naive loop.
for (int i = 0; i < elements.length; i++) {
addLast(elements[i]);
}
}
/**
* Inserts all elements from the given container to the end of this deque.
*
* @return Returns the number of elements actually added as a result of this
* call.
*/
public int addLast(final IntContainer container)
{
return addLast((Iterable extends IntCursor>) container);
}
/**
* Inserts all elements from the given iterable to the end of this deque.
*
* @return Returns the number of elements actually added as a result of this call.
*/
public int addLast(final Iterable extends IntCursor> iterable)
{
int size = 0;
for (final IntCursor cursor : iterable)
{
addLast(cursor.value);
size++;
}
return size;
}
/**
* {@inheritDoc}
*/
@Override
public int removeFirst()
{
assert size() > 0 : "The deque is empty.";
final int result = this.buffer[this.head];
this.head = ((this.head + 1 == this.buffer.length) ? 0 : this.head + 1);
return result;
}
/**
* {@inheritDoc}
*/
@Override
public int removeLast()
{
assert size() > 0 : "The deque is empty.";
this.tail = ((this.tail >= 1) ? this.tail - 1 : this.buffer.length - 1);
final int result = this.buffer[this.tail];
return result;
}
/**
* {@inheritDoc}
*/
@Override
public int getFirst()
{
assert size() > 0 : "The deque is empty.";
return this.buffer[this.head];
}
/**
* {@inheritDoc}
*/
@Override
public int getLast()
{
assert size() > 0 : "The deque is empty.";
return this.buffer[((this.tail >= 1) ? this.tail - 1 : this.buffer.length - 1)];
}
/**
* {@inheritDoc}
* The returned position is relative to the head,
* i.e w.r.t the {@link IntIndexedContainer}, index 0 is the head of the queue, size() - 1 is the last element position.
*/
@Override
public int removeFirstOccurrence(final int e1)
{
int pos = -1;
final int index = bufferIndexOf(e1);
if (index >= 0) {
pos = bufferIndexToPosition(index);
removeAtBufferIndex(index);
}
return pos;
}
/**
* Return the index of the first element equal to
* e1
. The index points to the {@link #buffer} array.
*
* @param e1 The element to look for.
* @return Returns the index in {@link #buffer} of the first element equal to e1
* or -1
if not found.
*/
public int bufferIndexOf(final int e1)
{
final int last = this.tail;
final int bufLen = this.buffer.length;
final int[] buffer = this.buffer;
for (int i = this.head; i != last; i = ((i + 1 == bufLen) ? 0 : i + 1))
{
if (((e1) == (buffer[i]))) {
return i;
}
}
return -1;
}
/**
* {@inheritDoc}
* The returned position is relative to the head,
* i.e w.r.t the {@link IntIndexedContainer}, index 0 is the head of the queue, size() - 1 is the last element position.
*/
@Override
public int removeLastOccurrence(final int e1)
{
int pos = -1;
final int index = lastBufferIndexOf(e1);
if (index >= 0) {
pos = bufferIndexToPosition(index);
removeAtBufferIndex(index);
}
return pos;
}
/**
* Return the index of the last element equal to
* e1
. The index points to the {@link #buffer} array.
*
* @param e1 The element to look for.
* @return Returns the index in {@link #buffer} of the first element equal to e1
* or -1
if not found.
*/
public int lastBufferIndexOf(final int e1)
{
final int bufLen = this.buffer.length;
final int last = ((this.head >= 1) ? this.head - 1 : bufLen - 1);
final int[] buffer = this.buffer;
for (int i = ((this.tail >= 1) ? this.tail - 1 : bufLen - 1); i != last; i = ((i >= 1) ? i - 1 : bufLen - 1))
{
if (((e1) == (buffer[i]))) {
return i;
}
}
return -1;
}
/**
* IntIndexedContainer methods
*/
/**
* {@inheritDoc}
* The returned position is relative to the head,
* i.e w.r.t the {@link IntIndexedContainer}, index 0 is the head of the queue, size() - 1 is the last element position.
*/
@Override
public int indexOf(final int e1) {
return bufferIndexToPosition(bufferIndexOf(e1));
}
/**
* {@inheritDoc}
* The returned position is relative to the head,
* i.e w.r.t the {@link IntIndexedContainer}, index 0 is the head of the queue, size() - 1 is the last element position.
*/
@Override
public int lastIndexOf(final int e1) {
return bufferIndexToPosition(lastBufferIndexOf(e1));
}
/**
* {@inheritDoc}
*/
@Override
public int removeAllOccurrences(final int e1)
{
int removed = 0;
final int last = this.tail;
final int bufLen = this.buffer.length;
final int[] buffer = this.buffer;
int from, to;
for (from = to = this.head; from != last; from = ((from + 1 == bufLen) ? 0 : from + 1))
{
if (((e1) == (buffer[from])))
{
removed++;
continue;
}
if (to != from)
{
buffer[to] = buffer[from];
}
to = ((to + 1 == bufLen) ? 0 : to + 1);
}
this.tail = to;
return removed;
}
/**
* Removes the element at index
in the internal
* {@link #buffer} array.
*
* @param index Index of the element to remove. The index must be located between
* {@link #head} and {@link #tail} in modulo {@link #buffer} arithmetic.
*/
public void removeAtBufferIndex(final int index)
{
assert (this.head <= this.tail
? index >= this.head && index < this.tail
: index >= this.head || index < this.tail) : "Index out of range (head="
+ this.head + ", tail=" + this.tail + ", index=" + index + ").";
// Cache fields in locals (hopefully moved to registers).
final int[] b = this.buffer;
final int bufLen = b.length;
final int lastIndex = bufLen - 1;
final int head = this.head;
final int tail = this.tail;
final int leftChunk = Math.abs(index - head) % bufLen;
final int rightChunk = Math.abs(tail - index) % bufLen;
if (leftChunk < rightChunk)
{
if (index >= head)
{
System.arraycopy(b, head, b, head + 1, leftChunk);
}
else
{
System.arraycopy(b, 0, b, 1, index);
b[0] = b[lastIndex];
System.arraycopy(b, head, b, head + 1, lastIndex - head);
}
this.head = ((head + 1 == bufLen) ? 0 : head + 1);
}
else
{
if (index < tail)
{
System.arraycopy(b, index + 1, b, index, rightChunk);
}
else
{
System.arraycopy(b, index + 1, b, index, lastIndex - index);
b[lastIndex] = b[0];
System.arraycopy(b, 1, b, 0, tail);
}
this.tail = ((tail >= 1) ? tail - 1 : bufLen - 1);
}
}
/**
* {@inheritDoc}
*/
@Override
public int size()
{
if (this.head <= this.tail)
{
return this.tail - this.head;
}
return (this.tail - this.head + this.buffer.length);
}
/**
* {@inheritDoc}
*/
@Override
public int capacity() {
return this.buffer.length;
}
/**
* {@inheritDoc}
* The internal array buffers are not released as a result of this call.
*/
@Override
public void clear()
{
this.head = this.tail = 0;
}
/**
* Compact the internal buffer to prepare sorting
* Beware, this changes the relative order of elements, so is only useful to
* not-stable sorts while sorting the WHOLE buffer !
*/
private void compactBeforeSorting()
{
if (this.head > this.tail)
{
final int size = size();
//pack the separated chunk to the beginning of the buffer
System.arraycopy(this.buffer, this.head, this.buffer, this.tail, this.buffer.length - this.head);
//reset of the positions
this.head = 0;
this.tail = size;
//for GC sake, reset hole elements now at the end of buffer
}
}
/**
* Release internal buffers of this deque and reallocate the smallest buffer possible.
*/
public void release()
{
this.head = this.tail = 0;
this.buffer = new int [this.resizer.round(IntArrayDeque.DEFAULT_CAPACITY)];
}
/**
* Ensures the internal buffer has enough free slots to store
* expectedAdditions
. Increases internal buffer size if needed.
*/
protected void ensureBufferSpace(final int expectedAdditions)
{
final int bufferLen = (this.buffer == null ? 0 : this.buffer.length);
final int elementsCount = size();
// +1 because there is always one empty slot in a deque.
if (elementsCount >= bufferLen - expectedAdditions - 1)
{
final int newSize = this.resizer.grow(bufferLen, elementsCount, expectedAdditions + 1);
assert newSize >= (elementsCount + expectedAdditions + 1) : "Resizer failed to" +
" return sensible new size: " + newSize + " <= "
+ (elementsCount + expectedAdditions);
final int[] newBuffer = new int [newSize];
if (bufferLen > 0)
{
toArray(newBuffer);
this.tail = elementsCount;
this.head = 0;
}
this.buffer = newBuffer;
}
}
/**
* Copies elements of this deque to an array. The content of the target
* array is filled from index 0 (head of the queue) to index size() - 1
* (tail of the queue).
*
* @param target The target array must be large enough to hold all elements.
* @return Returns the target argument for chaining.
*/
@Override
public int[] toArray(final int[] target)
{
assert target.length >= size() : "Target array must be >= " + size();
if (this.head < this.tail)
{
// The contents is not wrapped around. Just copy.
System.arraycopy(this.buffer, this.head, target, 0, size());
}
else if (this.head > this.tail)
{
// The contents is split. Merge elements from the following indexes:
// [head...buffer.length - 1][0, tail - 1]
final int rightCount = this.buffer.length - this.head;
System.arraycopy(this.buffer, this.head, target, 0, rightCount);
System.arraycopy(this.buffer, 0, target, rightCount, this.tail);
}
return target;
}
/**
* Clone this object. The returned clone will reuse the same array resizing strategy.
* It also realizes a trim-to- this.size() in the process.
*/
@Override
public IntArrayDeque clone()
{
/* */
//real constructor call
final IntArrayDeque cloned = new IntArrayDeque(this.size(), this.resizer);
cloned.defaultValue = this.defaultValue;
//copied in-order by construction.
cloned.addLast(this);
return cloned;
}
/**
* An iterator implementation for {@link ObjectArrayDeque#iterator}.
*/
public final class ValueIterator extends AbstractIterator
{
public final IntCursor cursor;
private int remaining;
public ValueIterator()
{
this.cursor = new IntCursor();
this.cursor.index = ((IntArrayDeque.this.head >= 1) ? IntArrayDeque.this.head - 1 : IntArrayDeque.this.buffer.length - 1);
this.remaining = IntArrayDeque.this.size();
}
@Override
protected IntCursor fetch()
{
if (this.remaining == 0) {
return done();
}
this.remaining--;
this.cursor.value = IntArrayDeque.this.buffer[this.cursor.index = ((this.cursor.index + 1 == IntArrayDeque.this.buffer.length) ? 0 : this.cursor.index + 1)];
return this.cursor;
}
}
/**
* An iterator implementation for {@link ObjectArrayDeque#descendingIterator()}.
*/
public final class DescendingValueIterator extends AbstractIterator
{
public final IntCursor cursor;
private int remaining;
public DescendingValueIterator()
{
this.cursor = new IntCursor();
this.cursor.index = IntArrayDeque.this.tail;
this.remaining = IntArrayDeque.this.size();
}
@Override
protected IntCursor fetch()
{
if (this.remaining == 0) {
return done();
}
this.remaining--;
this.cursor.value = IntArrayDeque.this.buffer[this.cursor.index = ((this.cursor.index >= 1) ? this.cursor.index - 1 : IntArrayDeque.this.buffer.length - 1)];
return this.cursor;
}
}
/**
* Returns a cursor over the values of this deque (in head to tail order). The
* iterator is implemented as a cursor and it returns the same cursor instance
* on every call to {@link Iterator#next()} (to avoid boxing of primitive types). To
* read the current value (or index in the deque's buffer) use the cursor's public
* fields. An example is shown below.
*
*
* for (IntValueCursor c : intDeque)
* {
* System.out.println("buffer index="
* + c.index + " value=" + c.value);
* }
*
* @return
*/
@Override
public ValueIterator iterator()
{
//return new ValueIterator();
return this.valueIteratorPool.borrow();
}
/**
* Returns a cursor over the values of this deque (in tail to head order). The
* iterator is implemented as a cursor and it returns the same cursor instance
* on every call to {@link Iterator#next()} (to avoid boxing of primitive types). To
* read the current value (or index in the deque's buffer) use the cursor's public
* fields. An example is shown below.
*
*
* for (Iterator i = intDeque.descendingIterator(); i.hasNext(); )
* {
* final IntCursor c = i.next();
* System.out.println("buffer index="
* + c.index + " value=" + c.value);
* }
*
* @return
*/
@Override
public DescendingValueIterator descendingIterator()
{
//return new DescendingValueIterator();
return this.descendingValueIteratorPool.borrow();
}
/**
* {@inheritDoc}
*/
@Override
public T forEach(final T procedure)
{
forEach(procedure, this.head, this.tail);
return procedure;
}
/**
* Applies procedure
to a slice of the deque,
* fromIndex
, inclusive, to toIndex
,
* exclusive, indices are in {@link #buffer} array.
*/
private void forEach(final IntProcedure procedure, final int fromIndex, final int toIndex)
{
final int[] buffer = this.buffer;
for (int i = fromIndex; i != toIndex; i = ((i + 1 == buffer.length) ? 0 : i + 1))
{
procedure.apply(buffer[i]);
}
}
/**
* {@inheritDoc}
*/
@Override
public T forEach(final T predicate)
{
final int fromIndex = this.head;
final int toIndex = this.tail;
final int[] buffer = this.buffer;
for (int i = fromIndex; i != toIndex; i = ((i + 1 == buffer.length) ? 0 : i + 1))
{
if (!predicate.apply(buffer[i])) {
break;
}
}
return predicate;
}
/**
* Applies procedure
to all elements of this deque, tail to head.
*/
@Override
public T descendingForEach(final T procedure)
{
descendingForEach(procedure, this.head, this.tail);
return procedure;
}
/**
* Applies procedure
to a slice of the deque,
* toIndex
, exclusive, down to fromIndex
, inclusive.
*/
private void descendingForEach(final IntProcedure procedure,
final int fromIndex, final int toIndex)
{
if (fromIndex == toIndex) {
return;
}
final int[] buffer = this.buffer;
int i = toIndex;
do
{
i = ((i >= 1) ? i - 1 : buffer.length - 1);
procedure.apply(buffer[i]);
} while (i != fromIndex);
}
/**
* {@inheritDoc}
*/
@Override
public T descendingForEach(final T predicate)
{
descendingForEach(predicate, this.head, this.tail);
return predicate;
}
/**
* Applies predicate
to a slice of the deque,
* toIndex
, exclusive, down to fromIndex
, inclusive
* or until the predicate returns false
.
* Indices are in {@link #buffer} array.
*/
private void descendingForEach(final IntPredicate predicate,
final int fromIndex, final int toIndex)
{
if (fromIndex == toIndex) {
return;
}
final int[] buffer = this.buffer;
int i = toIndex;
do
{
i = ((i >= 1) ? i - 1 : buffer.length - 1);
if (!predicate.apply(buffer[i])) {
break;
}
} while (i != fromIndex);
}
/**
* {@inheritDoc}
*/
@Override
public int removeAll(final IntPredicate predicate)
{
int removed = 0;
final int last = this.tail;
final int bufLen = this.buffer.length;
final int[] buffer = this.buffer;
int from, to;
from = to = this.head;
try
{
for (from = to = this.head; from != last; from = ((from + 1 == bufLen) ? 0 : from + 1))
{
if (predicate.apply(buffer[from]))
{
removed++;
continue;
}
if (to != from)
{
buffer[to] = buffer[from];
}
to = ((to + 1 == bufLen) ? 0 : to + 1);
}
}
finally
{
// Keep the deque in consistent state even if the predicate throws an exception.
for (; from != last; from = ((from + 1 == bufLen) ? 0 : from + 1))
{
if (to != from)
{
buffer[to] = buffer[from];
}
to = ((to + 1 == bufLen) ? 0 : to + 1);
}
this.tail = to;
}
return removed;
}
/**
* {@inheritDoc}
*/
@Override
public boolean contains(final int e)
{
final int fromIndex = this.head;
final int toIndex = this.tail;
final int[] buffer = this.buffer;
for (int i = fromIndex; i != toIndex; i = ((i + 1 == buffer.length) ? 0 : i + 1))
{
if (((e) == (buffer[i]))) {
return true;
}
}
return false;
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode()
{
int h = 1;
final int fromIndex = this.head;
final int toIndex = this.tail;
final int[] buffer = this.buffer;
for (int i = fromIndex; i != toIndex; i = ((i + 1 == buffer.length) ? 0 : i + 1))
{
h = 31 * h + Internals.rehash(buffer[i]);
}
return h;
}
/**
* {@inheritDoc}
*/
@Override
/* */
public boolean equals(final Object obj)
{
if (obj != null)
{
if (obj == this) {
return true;
}
if (obj instanceof IntDeque)
{
final IntDeque other = (IntDeque) obj;
if (other.size() != this.size()) {
return false;
}
final int fromIndex = this.head;
final int[] buffer = this.buffer;
int i = fromIndex;
//request a pooled iterator
final Iterator it = other.iterator();
IntCursor c;
while (it.hasNext())
{
c = it.next();
if (!((c.value) == (buffer[i])))
{
//if iterator was pooled, recycled it
if (it instanceof AbstractIterator>)
{
((AbstractIterator>) it).release();
}
return false;
}
i = ((i + 1 == buffer.length) ? 0 : i + 1);
}
return true;
} //end if IntDeque
else if (obj instanceof IntIndexedContainer)
{
final IntIndexedContainer other = (IntIndexedContainer) obj;
return other.size() == this.size() &&
allIndexesEqual(this, (IntIndexedContainer) other, this.size());
}
}
return false;
}
/**
* Compare index-aligned IntIndexedContainer objects
*/
private boolean allIndexesEqual(
final IntIndexedContainer b1,
final IntIndexedContainer b2, final int length)
{
for (int i = 0; i < length; i++)
{
final int o1 = b1.get(i);
final int o2 = b2.get(i);
if (!((o1) == (o2)))
{
return false;
}
}
return true;
}
/**
* Returns a new object of this class with no need to declare generic type (shortcut
* instead of using a constructor).
*/
public static/* */
IntArrayDeque newInstance()
{
return new IntArrayDeque();
}
/**
* Returns a new object of this class with no need to declare generic type (shortcut
* instead of using a constructor).
*/
public static/* */
IntArrayDeque newInstanceWithCapacity(final int initialCapacity)
{
return new IntArrayDeque(initialCapacity);
}
/**
* Create a new deque by pushing a variable number of arguments to the end of it.
*/
public static/* */
IntArrayDeque from(final int... elements)
{
final IntArrayDeque coll = new IntArrayDeque(elements.length);
coll.addLast(elements);
return coll;
}
/**
* Create a new deque by pushing a variable number of arguments to the end of it.
*/
public static/* */
IntArrayDeque from(final IntArrayDeque container)
{
return new IntArrayDeque(container);
}
////////////////////////////
/**
* In-place sort the dequeue from [beginIndex, endIndex[
* by natural ordering (smaller first)
* @param beginIndex the start index to be sorted
* @param endIndex the end index to be sorted (excluded)
*/
public void sort(int beginIndex, int endIndex)
{
assert endIndex <= size();
if (endIndex - beginIndex > 1)
{
IntSort.quicksort(this, beginIndex, endIndex);
}
}
/**
* In-place sort the dequeue from [beginIndex, endIndex[
* using a IntComparator *
* This routine uses Dual-pivot Quicksort, from [Yaroslavskiy 2009] *
* @param beginIndex the start index to be sorted
* @param endIndex the end index to be sorted (excluded)
*/
public void sort(
final int beginIndex, final int endIndex,
IntComparator
comp)
{
assert endIndex <= size();
if (endIndex - beginIndex > 1)
{
IntSort.quicksort(this, beginIndex, endIndex, comp);
}
}
/**
* In-place sort the whole dequeue by natural ordering (smaller first)
*
* This routine uses Dual-pivot Quicksort, from [Yaroslavskiy 2009].
*
* @param beginIndex
* @param endIndex
*/
public void sort()
{
if (size() > 1)
{
compactBeforeSorting();
IntSort.quicksort(buffer, head, tail);
}
}
////////////////////////////
/**
* In-place sort the whole dequeue
* using a IntComparator *
* This routine uses Dual-pivot Quicksort, from [Yaroslavskiy 2009] *
*/
public void sort(
IntComparator
comp)
{
if (size() > 1)
{
compactBeforeSorting();
IntSort.quicksort(this.buffer, this.head, this.tail, comp);
}
}
/**
* IntIndexedContainer methods
*/
/**
* {@inheritDoc}
*/
@Override
public void add(final int e1) {
addLast(e1);
}
/**
* Beware: This operation is not supported.
*/
@Override
public void insert(final int index, final int e1) {
throw new UnsupportedOperationException("insert(final int index, final int e1) operation is not supported on IntArrayDeque");
}
/**
* {@inheritDoc}
* The position is relative to the head,
* i.e w.r.t the {@link IntIndexedContainer}, index 0 is the head of the queue, size() - 1 is the last element position.
*/
@Override
public int set(final int index, final int e1) {
assert (index >= 0 && index < size()) : "Index " + index + " out of bounds [" + 0 + ", " + size() + ").";
final int indexInBuffer = ((index + this.head < this.buffer.length) ? index + this.head : index + this.head - this.buffer.length);
final int previous = this.buffer[indexInBuffer];
this.buffer[indexInBuffer] = e1;
return previous;
}
/**
* {@inheritDoc}
* The position is relative to the head,
* i.e w.r.t the {@link IntIndexedContainer}, index 0 is the head of the queue, size() - 1 is the last element position.
*/
@Override
public int get(final int index) {
assert (index >= 0 && index < size()) : "Index " + index + " out of bounds [" + 0 + ", " + size() + ").";
return this.buffer[((index + this.head < this.buffer.length) ? index + this.head : index + this.head - this.buffer.length)];
}
/**
* {@inheritDoc}
* The position is relative to the head,
* i.e w.r.t the {@link IntIndexedContainer}, index 0 is the head of the queue, size() - 1 is the last element position.
*/
@Override
public int remove(final int index) {
assert (index >= 0 && index < size()) : "Index " + index + " out of bounds [" + 0 + ", " + size() + ").";
final int indexInBuffer = ((index + this.head < this.buffer.length) ? index + this.head : index + this.head - this.buffer.length);
final int previous = this.buffer[indexInBuffer];
removeAtBufferIndex(indexInBuffer);
return previous;
}
/**
* Beware: This operation is not supported.
*/
@Override
public void removeRange(final int fromIndex, final int toIndex) {
throw new UnsupportedOperationException("removeRange(final int fromIndex, final int toIndex) operation is not supported on IntArrayDeque");
}
/**
* convert the internal {@link #buffer} index to equivalent {@link #IntIndexedContainer}
* position.
* @param bufferIndex
* @return
*/
private int bufferIndexToPosition(final int bufferIndex) {
int pos = -1;
if (bufferIndex >= 0) {
pos = bufferIndex - this.head;
if (pos < 0) {
//fold it
pos += this.buffer.length;
}
}
return pos;
}
}