com.landawn.abacus.util.stream.SpinedBuffer Maven / Gradle / Ivy
/*
* Copyright (C) 2021 HaiYang Li
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.landawn.abacus.util.stream;
import static com.landawn.abacus.util.stream.StreamBase.ERROR_MSG_FOR_NO_SUCH_EX;
import java.util.AbstractCollection;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.function.Consumer;
import java.util.function.DoubleConsumer;
import java.util.function.IntConsumer;
import java.util.function.LongConsumer;
import com.landawn.abacus.util.DoubleIterator;
import com.landawn.abacus.util.IntIterator;
import com.landawn.abacus.util.LongIterator;
import com.landawn.abacus.util.N;
import com.landawn.abacus.util.ObjIterator;
import com.landawn.abacus.util.cs;
/**
*
*
* @param
*/
final class SpinedBuffer extends AbstractCollection implements Consumer {
private static final int CHUNK_SIZE = 9;
private static final int SPINE_SIZE_TO_INCREASE = 8;
private E[][] spine = null; //NOSONAR
private E[] curChunk = (E[]) N.EMPTY_OBJECT_ARRAY; //NOSONAR
private int size = 0; //NOSONAR
public SpinedBuffer() {
this(CHUNK_SIZE);
}
/**
*
* @param initialCapacity
* @throws IllegalArgumentException
*/
public SpinedBuffer(final int initialCapacity) throws IllegalArgumentException {
N.checkArgNotNegative(initialCapacity, "initialCapacity"); //NOSONAR
if (initialCapacity > 0) {
curChunk = (E[]) new Object[initialCapacity];
}
}
/**
*
* @param t
*/
@Override
public void accept(final E t) {
this.add(t);
}
/**
*
* @param e
* @return
*/
@Override
public boolean add(final E e) {
if (size < curChunk.length) {
curChunk[size] = e;
} else if (curChunk.length == 0) {
curChunk = (E[]) new Object[CHUNK_SIZE];
curChunk[size] = e;
} else {
if (spine == null) {
spine = (E[][]) new Object[SPINE_SIZE_TO_INCREASE][];
spine[0] = curChunk;
spine[1] = (E[]) new Object[CHUNK_SIZE];
curChunk = spine[1];
} else {
final int chunkIndex = (size - spine[0].length) / CHUNK_SIZE + 1;
if (spine.length <= chunkIndex) {
spine = N.copyOf(spine, spine.length + SPINE_SIZE_TO_INCREASE);
}
if (spine[chunkIndex] == null) {
curChunk = (E[]) new Object[CHUNK_SIZE];
spine[chunkIndex] = curChunk;
}
}
curChunk[(size - spine[0].length) % CHUNK_SIZE] = e;
}
size++;
return true;
}
/**
*
* @param o
* @return
* @throws UnsupportedOperationException
* @deprecated Unsupported operation.
*/
@Deprecated
@Override
public boolean remove(final Object o) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
/**
*
* @param c
* @return
* @throws UnsupportedOperationException
* @deprecated Unsupported operation.
*/
@Deprecated
@Override
public boolean removeAll(final Collection> c) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
@Override
public Iterator iterator() {
if (N.isEmpty(spine)) {
return ObjIterator.of(curChunk, 0, size);
} else {
final int localSize = size();
return new ObjIterator<>() {
private final E[] firstChunk = spine[0];
private final int firstChunkLen = firstChunk.length;
private int cursor = 0;
private E next = null;
@Override
public boolean hasNext() {
return cursor < localSize;
}
@Override
public E next() {
if (cursor >= localSize) {
throw new NoSuchElementException(ERROR_MSG_FOR_NO_SUCH_EX);
}
if (cursor < firstChunkLen) {
return firstChunk[cursor++];
} else {
next = spine[(cursor - firstChunkLen) / CHUNK_SIZE + 1][(cursor - firstChunkLen) % CHUNK_SIZE];
cursor++;
return next;
}
}
};
}
}
@Override
public int size() {
return size;
}
static class OfInt implements IntConsumer {
private int[][] spine = null;
private int[] curChunk = N.EMPTY_INT_ARRAY;
private int size = 0;
public OfInt() {
this(CHUNK_SIZE);
}
public OfInt(final int initialCapacity) throws IllegalArgumentException {
N.checkArgNotNegative(initialCapacity, cs.initialCapacity);
if (initialCapacity > 0) {
curChunk = new int[initialCapacity];
}
}
@Override
public void accept(final int t) {
this.add(t);
}
@SuppressWarnings("SameReturnValue")
public boolean add(final int e) {
if (size < curChunk.length) {
curChunk[size] = e;
} else if (curChunk.length == 0) {
curChunk = new int[CHUNK_SIZE];
curChunk[size] = e;
} else {
if (spine == null) {
spine = new int[SPINE_SIZE_TO_INCREASE][];
spine[0] = curChunk;
spine[1] = new int[CHUNK_SIZE];
curChunk = spine[1];
} else {
final int chunkIndex = (size - spine[0].length) / CHUNK_SIZE + 1;
if (spine.length <= chunkIndex) {
spine = N.copyOf(spine, spine.length + SPINE_SIZE_TO_INCREASE);
}
if (spine[chunkIndex] == null) {
curChunk = new int[CHUNK_SIZE];
spine[chunkIndex] = curChunk;
}
}
curChunk[(size - spine[0].length) % CHUNK_SIZE] = e;
}
size++;
return true;
}
public IntIterator iterator() {
if (N.isEmpty(spine)) {
return IntIterator.of(curChunk, 0, size);
} else {
final int localSize = size();
return new IntIterator() {
private final int[] firstChunk = spine[0];
private final int firstChunkLen = firstChunk.length;
private int cursor = 0;
private int next = 0;
@Override
public boolean hasNext() {
return cursor < localSize;
}
@Override
public int nextInt() {
if (cursor >= localSize) {
throw new NoSuchElementException(ERROR_MSG_FOR_NO_SUCH_EX);
}
if (cursor < firstChunkLen) {
return firstChunk[cursor++];
} else {
next = spine[(cursor - firstChunkLen) / CHUNK_SIZE + 1][(cursor - firstChunkLen) % CHUNK_SIZE];
cursor++;
return next;
}
}
};
}
}
public int size() {
return size;
}
}
static class OfLong implements LongConsumer {
private long[][] spine = null;
private long[] curChunk = N.EMPTY_LONG_ARRAY;
private int size = 0;
public OfLong() {
this(CHUNK_SIZE);
}
public OfLong(final int initialCapacity) throws IllegalArgumentException {
N.checkArgNotNegative(initialCapacity, cs.initialCapacity);
if (initialCapacity > 0) {
curChunk = new long[initialCapacity];
}
}
@Override
public void accept(final long t) {
this.add(t);
}
@SuppressWarnings("SameReturnValue")
public boolean add(final long e) {
if (size < curChunk.length) {
curChunk[size] = e;
} else if (curChunk.length == 0) {
curChunk = new long[CHUNK_SIZE];
curChunk[size] = e;
} else {
if (spine == null) {
spine = new long[SPINE_SIZE_TO_INCREASE][];
spine[0] = curChunk;
spine[1] = new long[CHUNK_SIZE];
curChunk = spine[1];
} else {
final int chunkIndex = (size - spine[0].length) / CHUNK_SIZE + 1;
if (spine.length <= chunkIndex) {
spine = N.copyOf(spine, spine.length + SPINE_SIZE_TO_INCREASE);
}
if (spine[chunkIndex] == null) {
curChunk = new long[CHUNK_SIZE];
spine[chunkIndex] = curChunk;
}
}
curChunk[(size - spine[0].length) % CHUNK_SIZE] = e;
}
size++;
return true;
}
public LongIterator iterator() {
if (N.isEmpty(spine)) {
return LongIterator.of(curChunk, 0, size);
} else {
final int localSize = size();
return new LongIterator() {
private final long[] firstChunk = spine[0];
private final int firstChunkLen = firstChunk.length;
private int cursor = 0;
private long next = 0;
@Override
public boolean hasNext() {
return cursor < localSize;
}
@Override
public long nextLong() {
if (cursor >= localSize) {
throw new NoSuchElementException(ERROR_MSG_FOR_NO_SUCH_EX);
}
if (cursor < firstChunkLen) {
return firstChunk[cursor++];
} else {
next = spine[(cursor - firstChunkLen) / CHUNK_SIZE + 1][(cursor - firstChunkLen) % CHUNK_SIZE];
cursor++;
return next;
}
}
};
}
}
public int size() {
return size;
}
}
static class OfDouble implements DoubleConsumer {
private double[][] spine = null;
private double[] curChunk = N.EMPTY_DOUBLE_ARRAY;
private int size = 0;
public OfDouble() {
this(CHUNK_SIZE);
}
public OfDouble(final int initialCapacity) throws IllegalArgumentException {
N.checkArgNotNegative(initialCapacity, cs.initialCapacity);
if (initialCapacity > 0) {
curChunk = new double[initialCapacity];
}
}
@Override
public void accept(final double t) {
this.add(t);
}
@SuppressWarnings("SameReturnValue")
public boolean add(final double e) {
if (size < curChunk.length) {
curChunk[size] = e;
} else if (curChunk.length == 0) {
curChunk = new double[CHUNK_SIZE];
curChunk[size] = e;
} else {
if (spine == null) {
spine = new double[SPINE_SIZE_TO_INCREASE][];
spine[0] = curChunk;
spine[1] = new double[CHUNK_SIZE];
curChunk = spine[1];
} else {
final int chunkIndex = (size - spine[0].length) / CHUNK_SIZE + 1;
if (spine.length <= chunkIndex) {
spine = N.copyOf(spine, spine.length + SPINE_SIZE_TO_INCREASE);
}
if (spine[chunkIndex] == null) {
curChunk = new double[CHUNK_SIZE];
spine[chunkIndex] = curChunk;
}
}
curChunk[(size - spine[0].length) % CHUNK_SIZE] = e;
}
size++;
return true;
}
public DoubleIterator iterator() {
if (N.isEmpty(spine)) {
return DoubleIterator.of(curChunk, 0, size);
} else {
final int localSize = size();
return new DoubleIterator() {
private final double[] firstChunk = spine[0];
private final int firstChunkLen = firstChunk.length;
private int cursor = 0;
private double next = 0;
@Override
public boolean hasNext() {
return cursor < localSize;
}
@Override
public double nextDouble() {
if (cursor >= localSize) {
throw new NoSuchElementException(ERROR_MSG_FOR_NO_SUCH_EX);
}
if (cursor < firstChunkLen) {
return firstChunk[cursor++];
} else {
next = spine[(cursor - firstChunkLen) / CHUNK_SIZE + 1][(cursor - firstChunkLen) % CHUNK_SIZE];
cursor++;
return next;
}
}
};
}
}
public int size() {
return size;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy