All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.carrotsearch.hppcrt.lists.ByteArrayList Maven / Gradle / Ivy

Go to download

High Performance Primitive Collections Realtime (fork of HPPC from Carrotsearch) Fundamental data structures (maps, sets, lists, queues, heaps, sorts) generated for combinations of object and primitive types to conserve JVM memory and speed up execution. The Realtime fork intends to extend the existing collections, by tweaking to remove any dynamic allocations at runtime, and to obtain low variance execution times whatever the input nature.

There is a newer version: 0.7.5
Show newest version
package com.carrotsearch.hppcrt.lists;

import java.util.*;

import com.carrotsearch.hppcrt.*;
import com.carrotsearch.hppcrt.cursors.*;
import com.carrotsearch.hppcrt.hash.BitMixer;
import com.carrotsearch.hppcrt.lists.ByteLinkedList.ValueIterator;
import com.carrotsearch.hppcrt.predicates.*;
import com.carrotsearch.hppcrt.procedures.*;
import com.carrotsearch.hppcrt.sorting.*;
import com.carrotsearch.hppcrt.strategies.*;

  
/**
 * An array-backed list of bytes. 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.
 * It also has some dedicated methods to easily push, pop, and discard elements
 * from the end of the array, emulating so a {@linkplain Stack java.util.Stack}.
 * (see "Stack-emulating methods)
 * 
 * 

See {@link ObjectArrayList} class for API similarities and differences against Java * Collections. */ @javax.annotation.Generated( date = "2016-01-27T20:51:54+0100", value = "KTypeArrayList.java") public class ByteArrayList extends AbstractByteCollection implements ByteIndexedContainer, Cloneable { /** * Internal array for storing the list. The array may be larger than the current size * ({@link #size()}). * *

* Direct list iteration: iterate buffer[i] for i in [0; size()[ *

*/ public byte [] buffer; /** * Current number of elements stored in {@link #buffer}. */ protected int elementsCount; /** * Buffer resizing strategy. */ protected final ArraySizingStrategy resizer; /** * internal pool of ValueIterator (must be created in constructor) */ protected final IteratorPool valueIteratorPool; /** * Default constructor: Create with default sizing strategy and initial capacity for storing * {@link Containers#DEFAULT_EXPECTED_ELEMENTS} elements. * * @see BoundedProportionalArraySizingStrategy */ public ByteArrayList() { this(Containers.DEFAULT_EXPECTED_ELEMENTS); } /** * Create with default sizing strategy and the given initial capacity. * * @see BoundedProportionalArraySizingStrategy */ public ByteArrayList(final int initialCapacity) { this(initialCapacity, new BoundedProportionalArraySizingStrategy()); } /** * Create with a custom buffer resizing strategy. */ public ByteArrayList(final int initialCapacity, final ArraySizingStrategy resizer) { assert resizer != null; this.resizer = resizer; //allocate internal buffer ensureBufferSpace(Math.max(Containers.DEFAULT_EXPECTED_ELEMENTS, initialCapacity)); this.valueIteratorPool = new IteratorPool(new ObjectFactory() { @Override public ValueIterator create() { return new ValueIterator(); } @Override public void initialize(final ValueIterator obj) { obj.cursor.index = -1; obj.size = ByteArrayList.this.size(); obj.buffer = ((ByteArrayList.this.buffer)); } @Override public void reset(final ValueIterator obj) { // for GC sake obj.buffer = null; } }); } /** * Creates a new list from elements of another container. */ public ByteArrayList(final ByteContainer container) { this(container.size()); addAll(container); } /** * {@inheritDoc} */ @Override public void add(final byte e1) { ensureBufferSpace(1); this.buffer[this.elementsCount++] = e1; } /** * Appends two elements at the end of the list. To add more than two elements, * use add (vararg-version) or access the buffer directly (tight * loop). */ public void add(final byte e1, final byte e2) { ensureBufferSpace(2); this.buffer[this.elementsCount++] = e1; this.buffer[this.elementsCount++] = e2; } /** * Add all elements from a range of given array to the list. * @param elements * @param start * @param length */ public void add(final byte[] elements, final int start, final int length) { assert length >= 0 : "Length must be >= 0"; ensureBufferSpace(length); System.arraycopy(elements, start, this.buffer, this.elementsCount, length); this.elementsCount += length; } /** * Vararg-signature method for adding elements at the end of the list. *

This method is handy, but costly if used in tight loops (anonymous * array passing)

* @param elements */ public void add(final byte... elements) { add(elements, 0, elements.length); } /** * Adds all elements from another container. * @param container * @return the number of elements added from the container */ public int addAll(final ByteContainer container) { return addAll((Iterable) container); } /** * Adds all elements from another iterable. * @param iterable * @return the number of elements added from the iterable */ public int addAll(final Iterable iterable) { int size = 0; for (final ByteCursor cursor : iterable) { add(cursor.value); size++; } return size; } /** * {@inheritDoc} */ @Override public void insert(final int index, final byte e1) { assert (index >= 0 && index <= size()) : "Index " + index + " out of bounds [" + 0 + ", " + size() + "]."; ensureBufferSpace(1); System.arraycopy(this.buffer, index, this.buffer, index + 1, this.elementsCount - index); this.buffer[index] = e1; this.elementsCount++; } /** * {@inheritDoc} */ @Override public byte get(final int index) { assert (index >= 0 && index < size()) : "Index " + index + " out of bounds [" + 0 + ", " + size() + "[."; return ((this.buffer[index])); } /** * {@inheritDoc} */ @Override public byte set(final int index, final byte e1) { assert (index >= 0 && index < size()) : "Index " + index + " out of bounds [" + 0 + ", " + size() + "[."; final byte v = ((this.buffer[index])); this.buffer[index] = e1; return v; } /** * {@inheritDoc} */ @Override public byte remove(final int index) { assert (index >= 0 && index < size()) : "Index " + index + " out of bounds [" + 0 + ", " + size() + "[."; final byte v = ((this.buffer[index])); if (index + 1 < this.elementsCount) { System.arraycopy(this.buffer, index + 1, this.buffer, index, this.elementsCount - index - 1); } this.elementsCount--; return v; } /** * {@inheritDoc} */ @Override public void removeRange(final int fromIndex, final int toIndex) { checkRangeBounds(fromIndex, toIndex); System.arraycopy(this.buffer, toIndex, this.buffer, fromIndex, this.elementsCount - toIndex); final int count = toIndex - fromIndex; this.elementsCount -= count; } /** * {@inheritDoc} */ @Override public int removeFirst(final byte e1) { final int index = indexOf(e1); if (index >= 0) { remove(index); } return index; } /** * {@inheritDoc} */ @Override public int removeLast(final byte e1) { final int index = lastIndexOf(e1); if (index >= 0) { remove(index); } return index; } /** * {@inheritDoc} */ @Override public int removeAll(final byte e1) { int to = 0; final byte[] buffer = ((this.buffer)); for (int from = 0; from < this.elementsCount; from++) { if (((e1) == (buffer[from]))) { continue; } if (to != from) { buffer[to] = buffer[from]; } to++; } final int deleted = this.elementsCount - to; this.elementsCount = to; return deleted; } /** * {@inheritDoc} */ @Override public boolean contains(final byte e1) { return indexOf(e1) >= 0; } /** * {@inheritDoc} */ @Override public int indexOf(final byte e1) { final byte[] buffer = ((this.buffer)); for (int i = 0; i < this.elementsCount; i++) { if (((e1) == (buffer[i]))) { return i; } } return -1; } /** * {@inheritDoc} */ @Override public int lastIndexOf(final byte e1) { final byte[] buffer = ((this.buffer)); for (int i = this.elementsCount - 1; i >= 0; i--) { if (((e1) == (buffer[i]))) { return i; } } return -1; } /** * Increases the capacity of this instance, if necessary, to ensure * that it can hold at least the number of elements specified by * the minimum capacity argument. */ public void ensureCapacity(final int minCapacity) { if (minCapacity > this.buffer.length) { ensureBufferSpace(minCapacity - size()); } } /** * Ensures the internal buffer has enough free slots to store * expectedAdditions. Increases internal buffer size if needed. */ @SuppressWarnings("boxing") protected void ensureBufferSpace(final int expectedAdditions) { final int bufferLen = (this.buffer == null ? 0 : this.buffer.length); if (this.elementsCount > bufferLen - expectedAdditions) { final int newSize = this.resizer.grow(bufferLen, this.elementsCount, expectedAdditions); try { final byte[] newBuffer = (new byte[(newSize)]); if (bufferLen > 0) { System.arraycopy(this.buffer, 0, newBuffer, 0, this.buffer.length); } this.buffer = newBuffer; } catch (final OutOfMemoryError e) { throw new BufferAllocationException( "Not enough memory to allocate buffers to grow from %d -> %d elements", e, bufferLen, newSize); } } } /** * Truncate or expand the list to the new size. If the list is truncated, the buffer * will not be reallocated (use {@link #trimToSize()} if you need a truncated buffer). * If the list is expanded, the elements beyond the current size are initialized with JVM-defaults * (zero or null values). */ public void resize(final int newSize) { if (newSize <= this.buffer.length) { if (newSize < this.elementsCount) { //there is no point in resetting to "null" elements //that becomes non-observable anyway. Still, //resetting is needed for GC in case of Objects because they may become "free" //if not referenced anywhere else. } else { //in all cases, the contract of resize if that new elements //are set to default values. Arrays.fill(this.buffer, this.elementsCount, newSize, ((byte)0)); } } else { ensureCapacity(newSize); } this.elementsCount = newSize; } /** * {@inheritDoc} */ @Override public int size() { return this.elementsCount; } /** * {@inheritDoc} */ @Override public int capacity() { return this.buffer.length; } /** * Trim the internal buffer to the current size. */ /* */ public void trimToSize() { if (size() != this.buffer.length) { this.buffer = (byte[]) toArray(); } } /** * Sets the number of stored elements to zero. */ @Override public void clear() { this.elementsCount = 0; } /** * Sets the number of stored elements to zero and releases the internal storage array. */ /* */ public void release() { this.buffer = (byte[]) ByteArrays.EMPTY; this.elementsCount = 0; } /** * {@inheritDoc} */ @Override public byte[] toArray(final byte[] target) { System.arraycopy(this.buffer, 0, target, 0, this.elementsCount); return target; } /** * Clone this object. */ @Override public ByteArrayList clone() { //placeholder final ByteArrayList cloned = new ByteArrayList(Containers.DEFAULT_EXPECTED_ELEMENTS, this.resizer); //clone raw buffers cloned.buffer = this.buffer.clone(); cloned.elementsCount = this.elementsCount; return cloned; } /** * {@inheritDoc} */ @Override public int hashCode() { int h = 1; final int max = this.elementsCount; final byte[] buffer = ((this.buffer)); for (int i = 0; i < max; i++) { h = 31 * h + BitMixer.mix(buffer[i]); } return h; } /** * {@inheritDoc} */ @Override /* */ public boolean equals(final Object obj) { if (obj != null) { if (obj == this) { return true; } //optimized for ByteArrayList if (obj instanceof ByteArrayList) { final ByteArrayList other = (ByteArrayList) obj; return other.size() == this.size() && rangeEquals(other.buffer, this.buffer, size()); } else if (obj instanceof ByteLinkedList) { //Access by index is slow, iterate by iterator when the other is a linked list final ByteLinkedList other = (ByteLinkedList) obj; if (other.size() != this.size()) { return false; } final ValueIterator it = this.iterator(); final ByteLinkedList.ValueIterator itOther = (ByteLinkedList.ValueIterator) other.iterator(); while (it.hasNext()) { final byte myVal = it.next().value; final byte otherVal = itOther.next().value; if (!((myVal) == (otherVal))) { //recycle it.release(); itOther.release(); return false; } } //end while itOther.release(); return true; } else if (obj instanceof ByteIndexedContainer) { final ByteIndexedContainer other = (ByteIndexedContainer) obj; return other.size() == this.size() && allIndexesEqual(this, (ByteIndexedContainer) other, this.size()); } } return false; } /** * Compare a range of values in two arrays. */ private boolean rangeEquals(byte [] b1, byte [] b2, int length) { for (int i = 0; i < length; i++) { if (!((b1[i]) == (b2[i]))) { return false; } } return true; } /** * Compare index-aligned ByteIndexedContainer objects */ private boolean allIndexesEqual(final ByteIndexedContainer b1, final ByteIndexedContainer b2, final int length) { for (int i = 0; i < length; i++) { final byte o1 = b1.get(i); final byte o2 = b2.get(i); if (!((o1) == (o2))) { return false; } } return true; } /** * An iterator implementation for {@link ObjectArrayList#iterator}. */ public final class ValueIterator extends AbstractIterator { public final ByteCursor cursor; private byte[] buffer; private int size; public ValueIterator() { this.cursor = new ByteCursor(); this.cursor.index = -1; this.size = ByteArrayList.this.size(); this.buffer = ((ByteArrayList.this.buffer)); } @Override protected ByteCursor fetch() { if (this.cursor.index + 1 == this.size) { return done(); } this.cursor.value = this.buffer[++this.cursor.index]; return this.cursor; } } /** * Returns an iterator over the values of this list. * 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 list's {@link #buffer} (which also matches index as in {@link #get(int)}), 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);
     * }
     * 
*/ @Override public ValueIterator iterator() { //return new ValueIterator(buffer, size()); return this.valueIteratorPool.borrow(); } /** * {@inheritDoc} */ @Override public T forEach(final T procedure) { return forEach(procedure, 0, size()); } /** * Applies procedure to a slice of the list, * fromIndex, inclusive, to toIndex, exclusive. */ @Override public T forEach(final T procedure, final int fromIndex, final int toIndex) { checkRangeBounds(fromIndex, toIndex); final byte[] buffer = ((this.buffer)); for (int i = fromIndex; i < toIndex; i++) { procedure.apply(buffer[i]); } return procedure; } /** * {@inheritDoc} */ @Override public int removeAll(final BytePredicate predicate) { final int elementsCount = this.elementsCount; final byte[] buffer = ((this.buffer)); int to = 0; int from = 0; try { for (; from < elementsCount; from++) { if (predicate.apply(buffer[from])) { continue; } if (to != from) { buffer[to] = buffer[from]; } to++; } } finally { // Keep the list in a consistent state, even if the predicate throws an exception. for (; from < elementsCount; from++) { if (to != from) { buffer[to] = buffer[from]; } to++; } this.elementsCount = to; } return elementsCount - to; } /** * {@inheritDoc} */ @Override public T forEach(final T predicate) { return forEach(predicate, 0, size()); } /** * Applies predicate to a slice of the list, * fromIndex, inclusive, to toIndex, * exclusive, or until predicate returns false. */ @Override public T forEach(final T predicate, final int fromIndex, final int toIndex) { checkRangeBounds(fromIndex, toIndex); final byte[] buffer = ((this.buffer)); for (int i = fromIndex; i < toIndex; i++) { if (!predicate.apply(buffer[i])) { break; } } return predicate; } /** * Returns a new object of this class with no need to declare generic type (shortcut * instead of using a constructor). */ public static/* */ ByteArrayList newInstance() { return new ByteArrayList(); } /** * Returns a new object of this class with no need to declare generic type (shortcut * instead of using a constructor). */ public static/* */ ByteArrayList newInstance(final int initialCapacity) { return new ByteArrayList(initialCapacity); } /** * Create a list from a variable number of arguments or an array of * byte. */ public static/* */ ByteArrayList from(final byte... elements) { final ByteArrayList list = new ByteArrayList(elements.length); list.add(elements); return list; } /** * Create a list from elements of another container. */ public static/* */ ByteArrayList from(final ByteContainer container) { return new ByteArrayList(container); } /** * In-place sort the list 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(final int beginIndex, final int endIndex) { ByteSort.quicksort(this.buffer, beginIndex, endIndex); } /** * In-place sort the whole list by natural ordering (smaller first) */ public void sort() { sort(0, this.elementsCount); } //////////////////////////// /** * In-place sort the list from [beginIndex, endIndex[ * using a ByteComparator * @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, ByteComparator comp) { ByteSort.quicksort(((this.buffer)), beginIndex, endIndex, comp); } /** * In-place sort the whole list * using a ByteComparator */ public void sort( ByteComparator comp) { sort(0, this.elementsCount, comp); } /////////////////////////////////////////////////////////////////////// // Stack-like methods /////////////////////////////////////////////////////////////////////// /** * Stack emulating method: Adds one byte at the end of the array, * equivalent of {@link #add(byte)} * @param e1 */ public void pushLast(final byte e1) { add(e1); } /** * Stack emulating method: Adds two bytes at the end of the array, * synonym of {@link #add(byte, byte)} * @param e1 * @param e2 */ public void pushLast(final byte e1, final byte e2) { add(e1, e2); } /** * Stack emulating method: Adds three bytes at the end of the array * @param e1 * @param e2 * @param e3 */ public void pushLast(final byte e1, final byte e2, final byte e3) { ensureBufferSpace(3); this.buffer[this.elementsCount++] = e1; this.buffer[this.elementsCount++] = e2; this.buffer[this.elementsCount++] = e3; } /** * Stack emulating method: Adds four bytes at the end of the array * @param e1 * @param e2 * @param e3 * @param e4 */ public void pushLast(final byte e1, final byte e2, final byte e3, final byte e4) { ensureBufferSpace(4); this.buffer[this.elementsCount++] = e1; this.buffer[this.elementsCount++] = e2; this.buffer[this.elementsCount++] = e3; this.buffer[this.elementsCount++] = e4; } /** * Stack emulating method: Add a range of array elements at the end of array, * synonym of {@link #add(byte[], int, int)} */ public void pushLast(final byte[] elements, final int start, final int len) { add(elements, start, len); } /** * Stack emulating method: Vararg-signature method for pushing elements at the end of the array. *

* This method is handy, but costly if used in tight loops (anonymous array * passing) *

*/ public final void pushLast(final byte... elements) { add(elements, 0, elements.length); } /** * Stack emulating method: Pushes all elements from another container at the end of the array, * synonym of {@link #addAll(ByteContainer)} */ public int pushAllLast(final ByteContainer container) { return addAll(container); } /** * Stack emulating method: Pushes all elements from another iterable to the end of the array, * synonym of {@link #addAll(Iterable)} * @param iterable */ public int pushAllLast(final Iterable iterable) { return addAll(iterable); } /** * Stack emulating method: Discard an arbitrary number of elements from the end of the array. * @param count */ public void discardLast(final int count) { assert this.elementsCount >= count; this.elementsCount -= count; /* */ } /** * Stack emulating method: Discard the last element of the array. */ public void discardLast() { assert this.elementsCount > 0; this.elementsCount--; /* */ } /** * Stack emulating method: Discard the last element of the array, and return it. */ public byte popLast() { assert this.elementsCount > 0; final byte v = ((this.buffer[--this.elementsCount])); /* */ return v; } /** * Stack emulating method: Peek at the last element on the array. */ public byte peekLast() { assert this.elementsCount > 0; return ((this.buffer[this.elementsCount - 1])); } private void checkRangeBounds(final int beginIndex, final int endIndex) { if (beginIndex > endIndex) { throw new IllegalArgumentException("Index beginIndex " + beginIndex + " is > endIndex " + endIndex); } if (beginIndex < 0) { throw new IndexOutOfBoundsException("Index beginIndex < 0"); } if (endIndex > this.elementsCount) { throw new IndexOutOfBoundsException("Index endIndex " + endIndex + " out of bounds [" + 0 + ", " + this.elementsCount + "]."); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy