package at.yawk.numaec;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.ConcurrentModificationException;
import org.eclipse.collections.api.LazyFloatIterable;
import org.eclipse.collections.api.FloatIterable;
import org.eclipse.collections.api.block.function.primitive.ObjectFloatIntToObjectFunction;
import org.eclipse.collections.api.block.function.primitive.ObjectFloatToObjectFunction;
import org.eclipse.collections.api.block.function.primitive.FloatToObjectFunction;
import org.eclipse.collections.api.block.predicate.primitive.FloatPredicate;
import org.eclipse.collections.api.block.procedure.primitive.FloatIntProcedure;
import org.eclipse.collections.api.block.procedure.primitive.FloatProcedure;
import org.eclipse.collections.api.iterator.MutableFloatIterator;
import org.eclipse.collections.api.iterator.FloatIterator;
import org.eclipse.collections.api.list.ListIterable;
import org.eclipse.collections.api.list.MutableList;
import org.eclipse.collections.api.list.primitive.ImmutableFloatList;
import org.eclipse.collections.api.list.primitive.MutableFloatList;
import org.eclipse.collections.api.list.primitive.FloatList;
import org.eclipse.collections.impl.lazy.primitive.ReverseFloatIterable;
import org.eclipse.collections.impl.list.mutable.primitive.SynchronizedFloatList;
import org.eclipse.collections.impl.list.mutable.primitive.UnmodifiableFloatList;
import org.eclipse.collections.impl.primitive.AbstractFloatIterable;
class FloatBufferListImpl extends AbstractFloatIterable implements FloatBufferList {
private static final int INITIAL_CAPACITY = 16;
final LargeByteBufferAllocator allocator;
LargeByteBuffer buffer;
int size;
FloatBufferListImpl(LargeByteBufferAllocator allocator) {
this.allocator = allocator;
buffer = LargeByteBuffer.EMPTY;
}
FloatBufferListImpl(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) * Float.BYTES;
}
@Override
public FloatIterator floatIterator() {
return new Itr();
}
@Override
public float[] toArray() {
float[] array = new float[size];
for (int i = 0; i < size; i++) {
array[i] = get(i);
}
return array;
}
@Override
public boolean contains(float value) {
for (int i = 0; i < size; i++) {
if (get(i) == value) {
return true;
}
}
return false;
}
@Override
public void forEach(FloatProcedure procedure) {
for (int i = 0; i < size; i++) {
procedure.value(get(i));
}
}
@Override
public void each(FloatProcedure procedure) {
forEach(procedure);
}
@Override
public float get(int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException();
} else {
return buffer.getFloat(scale(index));
}
}
@Override
public double
dotProduct(FloatList list) {
double
sum = 0;
int i = 0;
FloatIterator itr = list.floatIterator();
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(float value) {
int low = 0;
int high = size - 1;
while (low <= high) {
int mid = (low + high) / 2;
float 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(float value) {
for (int i = 0; i < size; i++) {
if (get(i) == value) {
return i;
}
}
return -1;
}
@Override
public int lastIndexOf(float value) {
for (int i = size - 1; i >= 0; i--) {
if (get(i) == value) {
return i;
}
}
return -1;
}
@Override
public float getLast() {
return get(size - 1);
}
@Override
public LazyFloatIterable asReversed() {
return ReverseFloatIterable.adapt(this);
}
@Override
public float getFirst() {
return get(0);
}
@Override
public FloatList select(FloatPredicate predicate) {
throw new UnsupportedOperationException();
}
@Override
public FloatList reject(FloatPredicate predicate) {
throw new UnsupportedOperationException();
}
@Override
public <V> ListIterable<V> collect(FloatToObjectFunction<? extends V> function) {
throw new UnsupportedOperationException();
}
@Override
public float detectIfNone(FloatPredicate predicate, float ifNone) {
for (int i = 0; i < size; i++) {
float element = get(i);
if (predicate.accept(element)) {
return element;
}
}
return ifNone;
}
@Override
public int count(FloatPredicate predicate) {
int count = 0;
for (int i = 0; i < size; i++) {
if (predicate.accept(get(i))) {
count++;
}
}
return count;
}
@Override
public boolean anySatisfy(FloatPredicate predicate) {
for (int i = 0; i < size; i++) {
float element = get(i);
if (predicate.accept(element)) {
return true;
}
}
return false;
}
@Override
public boolean allSatisfy(FloatPredicate predicate) {
for (int i = 0; i < size; i++) {
float element = get(i);
if (!predicate.accept(element)) {
return false;
}
}
return true;
}
@Override
public boolean noneSatisfy(FloatPredicate predicate) {
return !anySatisfy(predicate);
}
@Override
public <T> T injectInto(T injectedValue, ObjectFloatToObjectFunction<? 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, ObjectFloatIntToObjectFunction<? super T, ? extends T> function) {
for (int i = 0; i < size; i++) {
injectedValue = function.valueOf(injectedValue, get(i), i);
}
return injectedValue;
}
@Override
public double
sum() {
double
sum = 0;
for (int i = 0; i < size; i++) {
sum += get(i);
}
return sum;
}
@Override
public float max() {
float max = get(0);
for (int i = 1; i < size; i++) {
float item = get(i);
if (item > max) {
return item;
}
}
return max;
}
@Override
public float min() {
float min = get(0);
for (int i = 1; i < size; i++) {
float item = get(i);
if (item < min) {
return item;
}
}
return min;
}
@Override
public ImmutableFloatList toImmutable() {
throw new UnsupportedOperationException();
}
@Override
public FloatList distinct() {
throw new UnsupportedOperationException();
}
@Override
public void forEachWithIndex(FloatIntProcedure procedure) {
for (int i = 0; i < size; i++) {
procedure.value(get(i), i);
}
}
@Override
public FloatList toReversed() {
throw new UnsupportedOperationException();
}
@Override
public FloatList 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 FloatList) {
FloatList other = (FloatList) o;
int expectedSize = other.size();
if (expectedSize == this.size()) {
FloatIterator j = other.floatIterator();
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 FloatIterator {
int i;
@Override
public float next() {
return get(i++);
}
@Override
public boolean hasNext() {
return i < size;
}
}
public static class Mutable extends FloatBufferListImpl implements MutableFloatBufferList {
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, float 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.setFloat(scale(index), element);
size++;
}
}
@Override
public boolean addAllAtIndex(int index, float... 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.setFloat(scale(index + i), source[i]);
}
size += source.length;
return true;
}
}
@Override
public boolean addAllAtIndex(int index, FloatIterable 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));
FloatIterator itr = source.floatIterator();
for (int i = 0; i < expectedSize; i++) {
if (!itr.hasNext()) { throw new ConcurrentModificationException(); }
buffer.setFloat(scale(index + i), itr.next());
}
if (itr.hasNext()) { throw new ConcurrentModificationException(); }
size += expectedSize;
return true;
}
}
@Override
public float removeAtIndex(int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException();
} else {
float value = buffer.getFloat(scale(index));
if (size > 1) {
buffer.copyFrom(buffer, scale(index + 1), scale(index), scale(size - index - 1));
}
size--;
return value;
}
}
@Override
public float set(int index, float element) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException();
} else {
float old = buffer.getFloat(scale(index));
buffer.setFloat(scale(index), element);
return old;
}
}
@Override
public boolean add(float element) {
ensureCapacity(size + 1);
buffer.setFloat(scale(size), element);
size++;
return true;
}
@Override
public boolean addAll(float... source) {
ensureCapacity(size + source.length);
for (int i = 0; i < source.length; i++) {
buffer.setFloat(scale(i + size), source[i]);
}
size += source.length;
return source.length > 0;
}
@Override
public boolean addAll(FloatIterable source) {
int expectedSize = source.size();
ensureCapacity(size + expectedSize);
FloatIterator itr = source.floatIterator();
int i = 0;
while (itr.hasNext()) {
if (i > expectedSize) {
throw new ConcurrentModificationException();
}
buffer.setFloat(scale(i + size), itr.next());
i++;
}
size += i;
return i > 0;
}
@Override
public boolean remove(float value) {
int ix = indexOf(value);
if (ix == -1) {
return false;
} else {
removeAtIndex(ix);
return true;
}
}
@Override
public boolean removeAll(FloatIterable source) {
throw new UnsupportedOperationException();
}
@Override
public boolean removeAll(float... source) {
throw new UnsupportedOperationException();
}
@Override
public boolean retainAll(FloatIterable elements) {
throw new UnsupportedOperationException();
}
@Override
public boolean retainAll(float... source) {
throw new UnsupportedOperationException();
}
@Override
public void clear() {
size = 0;
}
@Override
public MutableFloatList with(float element) {
add(element);
return this;
}
@Override
public MutableFloatList without(float element) {
remove(element);
return this;
}
@Override
public MutableFloatList withAll(FloatIterable elements) {
addAll(elements);
return this;
}
@Override
public MutableFloatList withoutAll(FloatIterable elements) {
removeAll(elements);
return this;
}
@Override
public MutableFloatList reverseThis() {
throw new UnsupportedOperationException();
}
@Override
public MutableFloatList sortThis() {
throw new UnsupportedOperationException();
}
@Override
public MutableFloatList asUnmodifiable() {
return new UnmodifiableFloatList(this);
}
@Override
public MutableFloatList asSynchronized() {
return new SynchronizedFloatList(this);
}
@Override
public MutableFloatIterator floatIterator() {
return new Itr();
}
@Override
public MutableFloatList select(FloatPredicate predicate) {
throw new UnsupportedOperationException();
}
@Override
public MutableFloatList reject(FloatPredicate predicate) {
throw new UnsupportedOperationException();
}
@Override
public <V> MutableList<V> collect(FloatToObjectFunction<? extends V> function) {
throw new UnsupportedOperationException();
}
@Override
public MutableFloatList toReversed() {
throw new UnsupportedOperationException();
}
@Override
public MutableFloatList distinct() {
throw new UnsupportedOperationException();
}
@Override
public MutableFloatList subList(int fromIndex, int toIndex) {
throw new UnsupportedOperationException();
}
class Itr extends FloatBufferListImpl.Itr implements MutableFloatIterator {
int removalIndex = -1;
@Override
public float next() {
removalIndex = i;
return super.next();
}
@Override
public void remove() {
if (removalIndex == -1) { throw new IllegalStateException(); }
removeAtIndex(removalIndex);
i--;
removalIndex = -1;
}
}
}
}