package at.yawk.numaec;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.ConcurrentModificationException;
import org.eclipse.collections.api.LazyShortIterable;
import org.eclipse.collections.api.ShortIterable;
import org.eclipse.collections.api.block.function.primitive.ObjectShortIntToObjectFunction;
import org.eclipse.collections.api.block.function.primitive.ObjectShortToObjectFunction;
import org.eclipse.collections.api.block.function.primitive.ShortToObjectFunction;
import org.eclipse.collections.api.block.predicate.primitive.ShortPredicate;
import org.eclipse.collections.api.block.procedure.primitive.ShortIntProcedure;
import org.eclipse.collections.api.block.procedure.primitive.ShortProcedure;
import org.eclipse.collections.api.iterator.MutableShortIterator;
import org.eclipse.collections.api.iterator.ShortIterator;
import org.eclipse.collections.api.list.ListIterable;
import org.eclipse.collections.api.list.MutableList;
import org.eclipse.collections.api.list.primitive.ImmutableShortList;
import org.eclipse.collections.api.list.primitive.MutableShortList;
import org.eclipse.collections.api.list.primitive.ShortList;
import org.eclipse.collections.impl.lazy.primitive.ReverseShortIterable;
import org.eclipse.collections.impl.list.mutable.primitive.SynchronizedShortList;
import org.eclipse.collections.impl.list.mutable.primitive.UnmodifiableShortList;
import org.eclipse.collections.impl.primitive.AbstractShortIterable;
class ShortBufferListImpl extends AbstractShortIterable implements ShortBufferList {
private static final int INITIAL_CAPACITY = 16;
final LargeByteBufferAllocator allocator;
LargeByteBuffer buffer;
int size;
ShortBufferListImpl(LargeByteBufferAllocator allocator) {
this.allocator = allocator;
buffer = LargeByteBuffer.EMPTY;
}
ShortBufferListImpl(LargeByteBufferAllocator allocator, int initialCapacity) {
this.allocator = allocator;
buffer = allocator.allocate(scale(initialCapacity));
}
@Override
public void close() {
buffer.close();
buffer = null;
}
protected long scale(int index) {
return ((long) index) * Short.BYTES;
}
@Override
public ShortIterator shortIterator() {
return new Itr();
}
@Override
public short[] toArray() {
short[] array = new short[size];
for (int i = 0; i < size; i++) {
array[i] = get(i);
}
return array;
}
@Override
public boolean contains(short value) {
for (int i = 0; i < size; i++) {
if (get(i) == value) {
return true;
}
}
return false;
}
@Override
public void forEach(ShortProcedure procedure) {
for (int i = 0; i < size; i++) {
procedure.value(get(i));
}
}
@Override
public void each(ShortProcedure procedure) {
forEach(procedure);
}
@Override
public short get(int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException();
} else {
return buffer.getShort(scale(index));
}
}
@Override
public long
dotProduct(ShortList list) {
long
sum = 0;
int i = 0;
ShortIterator itr = list.shortIterator();
while (i < size && itr.hasNext()) {
sum += get(i++) * itr.next();
}
if (itr.hasNext() || i < size) {
throw new IllegalArgumentException("Size mismatch");
}
return sum;
}
@Override
public int binarySearch(short value) {
int low = 0;
int high = size - 1;
while (low <= high) {
int mid = (low + high) / 2;
short pivot = get(mid);
if (pivot < value) {
low = mid + 1;
} else if (pivot > value) {
high = mid - 1;
} else {
return mid;
}
}
return ~low;
}
@Override
public int indexOf(short value) {
for (int i = 0; i < size; i++) {
if (get(i) == value) {
return i;
}
}
return -1;
}
@Override
public int lastIndexOf(short value) {
for (int i = size - 1; i >= 0; i--) {
if (get(i) == value) {
return i;
}
}
return -1;
}
@Override
public short getLast() {
return get(size - 1);
}
@Override
public LazyShortIterable asReversed() {
return ReverseShortIterable.adapt(this);
}
@Override
public short getFirst() {
return get(0);
}
@Override
public ShortList select(ShortPredicate predicate) {
throw new UnsupportedOperationException();
}
@Override
public ShortList reject(ShortPredicate predicate) {
throw new UnsupportedOperationException();
}
@Override
public <V> ListIterable<V> collect(ShortToObjectFunction<? extends V> function) {
throw new UnsupportedOperationException();
}
@Override
public short detectIfNone(ShortPredicate predicate, short ifNone) {
for (int i = 0; i < size; i++) {
short element = get(i);
if (predicate.accept(element)) {
return element;
}
}
return ifNone;
}
@Override
public int count(ShortPredicate predicate) {
int count = 0;
for (int i = 0; i < size; i++) {
if (predicate.accept(get(i))) {
count++;
}
}
return count;
}
@Override
public boolean anySatisfy(ShortPredicate predicate) {
for (int i = 0; i < size; i++) {
short element = get(i);
if (predicate.accept(element)) {
return true;
}
}
return false;
}
@Override
public boolean allSatisfy(ShortPredicate predicate) {
for (int i = 0; i < size; i++) {
short element = get(i);
if (!predicate.accept(element)) {
return false;
}
}
return true;
}
@Override
public boolean noneSatisfy(ShortPredicate predicate) {
return !anySatisfy(predicate);
}
@Override
public <T> T injectInto(T injectedValue, ObjectShortToObjectFunction<? super T, ? extends T> function) {
for (int i = 0; i < size; i++) {
injectedValue = function.valueOf(injectedValue, get(i));
}
return injectedValue;
}
@Override
public <T> T injectIntoWithIndex(T injectedValue, ObjectShortIntToObjectFunction<? super T, ? extends T> function) {
for (int i = 0; i < size; i++) {
injectedValue = function.valueOf(injectedValue, get(i), i);
}
return injectedValue;
}
@Override
public long
sum() {
long
sum = 0;
for (int i = 0; i < size; i++) {
sum += get(i);
}
return sum;
}
@Override
public short max() {
short max = get(0);
for (int i = 1; i < size; i++) {
short item = get(i);
if (item > max) {
return item;
}
}
return max;
}
@Override
public short min() {
short min = get(0);
for (int i = 1; i < size; i++) {
short item = get(i);
if (item < min) {
return item;
}
}
return min;
}
@Override
public ImmutableShortList toImmutable() {
throw new UnsupportedOperationException();
}
@Override
public ShortList distinct() {
throw new UnsupportedOperationException();
}
@Override
public void forEachWithIndex(ShortIntProcedure procedure) {
for (int i = 0; i < size; i++) {
procedure.value(get(i), i);
}
}
@Override
public ShortList toReversed() {
throw new UnsupportedOperationException();
}
@Override
public ShortList subList(int fromIndex, int toIndex) {
throw new UnsupportedOperationException();
}
@Override
public int size() {
return size;
}
@Override
public void appendString(Appendable appendable, String start, String separator, String end) {
try {
appendable.append(start);
for (int i = 0; i < size; i++) {
if (i != 0) {
appendable.append(separator);
}
appendable.append(String.valueOf(get(i)));
}
appendable.append(end);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
@Override
public boolean equals(Object o) {
if (o instanceof ShortList) {
ShortList other = (ShortList) o;
int expectedSize = other.size();
if (expectedSize == this.size()) {
ShortIterator j = other.shortIterator();
int i = 0;
while (i < expectedSize) {
if (!j.hasNext()) { throw new ConcurrentModificationException(); }
if (j.next() != get(i)) { return false; }
i++;
}
if (j.hasNext()) { throw new ConcurrentModificationException(); }
return true;
} else {
return false;
}
} else {
return false;
}
}
@Override
public int hashCode() {
int hashCode = 1;
for (int i = 0; i < size(); i++) {
hashCode *= 31;
hashCode += get(i);
}
return hashCode;
}
class Itr implements ShortIterator {
int i;
@Override
public short next() {
return get(i++);
}
@Override
public boolean hasNext() {
return i < size;
}
}
public static class Mutable extends ShortBufferListImpl implements MutableShortBufferList {
Mutable(LargeByteBufferAllocator allocator) {
super(allocator);
}
Mutable(LargeByteBufferAllocator allocator, int initialCapacity) {
super(allocator, initialCapacity);
}
private void ensureCapacity(int capacity) {
long requiredCapacity = scale(capacity);
long currentCapacity = buffer.size();
if (requiredCapacity > currentCapacity) {
long newCapacity = currentCapacity == 0 ? scale(INITIAL_CAPACITY) : currentCapacity;
while (requiredCapacity > newCapacity) {
newCapacity += newCapacity >> 1;
}
LargeByteBuffer reallocated = buffer.reallocate(newCapacity);
if (reallocated != null) {
this.buffer = reallocated;
} else {
@SuppressWarnings("resource")
LargeByteBuffer swap = allocator.allocate(newCapacity);
try {
swap.copyFrom(buffer, 0, 0, scale(size));
LargeByteBuffer tmp = swap;
swap = this.buffer;
this.buffer = tmp;
} finally {
swap.close();
}
}
}
}
@Override
public void addAtIndex(int index, short element) {
if (index == size) {
add(element);
} else if (index < 0 || index > size) {
throw new IndexOutOfBoundsException();
} else {
ensureCapacity(size + 1);
buffer.copyFrom(buffer, scale(index), scale(index + 1), scale(size - index));
buffer.setShort(scale(index), element);
size++;
}
}
@Override
public boolean addAllAtIndex(int index, short... source) {
if (index == size) {
return addAll(source);
} else if (index < 0 || index > size) {
throw new IndexOutOfBoundsException();
} else if (source.length == 0) {
return false;
} else {
ensureCapacity(size + source.length);
buffer.copyFrom(buffer, scale(index), scale(index + source.length), scale(size - index));
for (int i = 0; i < source.length; i++) {
buffer.setShort(scale(index + i), source[i]);
}
size += source.length;
return true;
}
}
@Override
public boolean addAllAtIndex(int index, ShortIterable source) {
if (index == size) {
return addAll(source);
} else if (index < 0 || index > size) {
throw new IndexOutOfBoundsException();
} else if (source.isEmpty()) {
return false;
} else {
int expectedSize = source.size();
ensureCapacity(size + expectedSize);
buffer.copyFrom(buffer, scale(index), scale(index + expectedSize), scale(size - index));
ShortIterator itr = source.shortIterator();
for (int i = 0; i < expectedSize; i++) {
if (!itr.hasNext()) { throw new ConcurrentModificationException(); }
buffer.setShort(scale(index + i), itr.next());
}
if (itr.hasNext()) { throw new ConcurrentModificationException(); }
size += expectedSize;
return true;
}
}
@Override
public short removeAtIndex(int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException();
} else {
short value = buffer.getShort(scale(index));
if (size > 1) {
buffer.copyFrom(buffer, scale(index + 1), scale(index), scale(size - index - 1));
}
size--;
return value;
}
}
@Override
public short set(int index, short element) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException();
} else {
short old = buffer.getShort(scale(index));
buffer.setShort(scale(index), element);
return old;
}
}
@Override
public boolean add(short element) {
ensureCapacity(size + 1);
buffer.setShort(scale(size), element);
size++;
return true;
}
@Override
public boolean addAll(short... source) {
ensureCapacity(size + source.length);
for (int i = 0; i < source.length; i++) {
buffer.setShort(scale(i + size), source[i]);
}
size += source.length;
return source.length > 0;
}
@Override
public boolean addAll(ShortIterable source) {
int expectedSize = source.size();
ensureCapacity(size + expectedSize);
ShortIterator itr = source.shortIterator();
int i = 0;
while (itr.hasNext()) {
if (i > expectedSize) {
throw new ConcurrentModificationException();
}
buffer.setShort(scale(i + size), itr.next());
i++;
}
size += i;
return i > 0;
}
@Override
public boolean remove(short value) {
int ix = indexOf(value);
if (ix == -1) {
return false;
} else {
removeAtIndex(ix);
return true;
}
}
@Override
public boolean removeAll(ShortIterable source) {
throw new UnsupportedOperationException();
}
@Override
public boolean removeAll(short... source) {
throw new UnsupportedOperationException();
}
@Override
public boolean retainAll(ShortIterable elements) {
throw new UnsupportedOperationException();
}
@Override
public boolean retainAll(short... source) {
throw new UnsupportedOperationException();
}
@Override
public void clear() {
size = 0;
}
@Override
public MutableShortList with(short element) {
add(element);
return this;
}
@Override
public MutableShortList without(short element) {
remove(element);
return this;
}
@Override
public MutableShortList withAll(ShortIterable elements) {
addAll(elements);
return this;
}
@Override
public MutableShortList withoutAll(ShortIterable elements) {
removeAll(elements);
return this;
}
@Override
public MutableShortList reverseThis() {
throw new UnsupportedOperationException();
}
@Override
public MutableShortList sortThis() {
throw new UnsupportedOperationException();
}
@Override
public MutableShortList asUnmodifiable() {
return new UnmodifiableShortList(this);
}
@Override
public MutableShortList asSynchronized() {
return new SynchronizedShortList(this);
}
@Override
public MutableShortIterator shortIterator() {
return new Itr();
}
@Override
public MutableShortList select(ShortPredicate predicate) {
throw new UnsupportedOperationException();
}
@Override
public MutableShortList reject(ShortPredicate predicate) {
throw new UnsupportedOperationException();
}
@Override
public <V> MutableList<V> collect(ShortToObjectFunction<? extends V> function) {
throw new UnsupportedOperationException();
}
@Override
public MutableShortList toReversed() {
throw new UnsupportedOperationException();
}
@Override
public MutableShortList distinct() {
throw new UnsupportedOperationException();
}
@Override
public MutableShortList subList(int fromIndex, int toIndex) {
throw new UnsupportedOperationException();
}
class Itr extends ShortBufferListImpl.Itr implements MutableShortIterator {
int removalIndex = -1;
@Override
public short next() {
removalIndex = i;
return super.next();
}
@Override
public void remove() {
if (removalIndex == -1) { throw new IllegalStateException(); }
removeAtIndex(removalIndex);
i--;
removalIndex = -1;
}
}
}
}