org.elasticsearch.common.util.BigArrays Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of elasticsearch Show documentation
Show all versions of elasticsearch Show documentation
Elasticsearch subproject :server
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
package org.elasticsearch.common.util;
import org.apache.lucene.util.ArrayUtil;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.RamUsageEstimator;
import org.elasticsearch.common.breaker.CircuitBreaker;
import org.elasticsearch.common.breaker.CircuitBreakingException;
import org.elasticsearch.common.breaker.PreallocatedCircuitBreakerService;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.recycler.Recycler;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.core.Releasable;
import org.elasticsearch.core.Releasables;
import org.elasticsearch.indices.breaker.CircuitBreakerService;
import java.io.IOException;
import java.util.Arrays;
import static org.elasticsearch.common.util.BigDoubleArray.VH_PLATFORM_NATIVE_DOUBLE;
import static org.elasticsearch.common.util.BigFloatArray.VH_PLATFORM_NATIVE_FLOAT;
import static org.elasticsearch.common.util.BigIntArray.VH_PLATFORM_NATIVE_INT;
import static org.elasticsearch.common.util.BigLongArray.VH_PLATFORM_NATIVE_LONG;
/** Utility class to work with arrays. */
public class BigArrays {
public static final BigArrays NON_RECYCLING_INSTANCE = new BigArrays(null, null, CircuitBreaker.REQUEST);
/** Returns the next size to grow when working with parallel arrays that
* may have different page sizes or number of bytes per element. */
public static long overSize(long minTargetSize) {
return overSize(minTargetSize, PageCacheRecycler.PAGE_SIZE_IN_BYTES / 8, 1);
}
/** Return the next size to grow to that is >= minTargetSize
.
* Inspired from {@link ArrayUtil#oversize(int, int)} and adapted to play nicely with paging. */
public static long overSize(long minTargetSize, int pageSize, int bytesPerElement) {
if (minTargetSize < 0) {
throw new IllegalArgumentException("minTargetSize must be >= 0");
}
if (pageSize < 0) {
throw new IllegalArgumentException("pageSize must be > 0");
}
if (bytesPerElement <= 0) {
throw new IllegalArgumentException("bytesPerElement must be > 0");
}
long newSize;
if (minTargetSize < pageSize) {
newSize = Math.min(ArrayUtil.oversize((int) minTargetSize, bytesPerElement), pageSize);
} else {
final long pages = (minTargetSize + pageSize - 1) / pageSize; // ceil(minTargetSize/pageSize)
newSize = pages * pageSize;
}
return newSize;
}
static boolean indexIsInt(long index) {
return index == (int) index;
}
private abstract static class AbstractArrayWrapper extends AbstractArray implements BigArray {
static final long SHALLOW_SIZE = RamUsageEstimator.shallowSizeOfInstance(ByteArrayWrapper.class);
private final Releasable releasable;
private final long size;
AbstractArrayWrapper(BigArrays bigArrays, long size, Releasable releasable, boolean clearOnResize) {
super(bigArrays, clearOnResize);
this.releasable = releasable;
this.size = size;
}
@Override
public final long size() {
return size;
}
@Override
protected final void doClose() {
Releasables.close(releasable);
}
}
private static class ByteArrayWrapper extends AbstractArrayWrapper implements ByteArray {
private final byte[] array;
ByteArrayWrapper(BigArrays bigArrays, byte[] array, long size, Recycler.V releasable, boolean clearOnResize) {
super(bigArrays, size, releasable, clearOnResize);
this.array = array;
}
@Override
public long ramBytesUsed() {
return SHALLOW_SIZE + RamUsageEstimator.sizeOf(array);
}
@Override
public byte get(long index) {
assert indexIsInt(index);
return array[(int) index];
}
@Override
public byte set(long index, byte value) {
assert indexIsInt(index);
final byte ret = array[(int) index];
array[(int) index] = value;
return ret;
}
@Override
public boolean get(long index, int len, BytesRef ref) {
assert indexIsInt(index);
ref.bytes = array;
ref.offset = (int) index;
ref.length = len;
return false;
}
@Override
public void set(long index, byte[] buf, int offset, int len) {
assert indexIsInt(index);
System.arraycopy(buf, offset, array, (int) index, len);
}
@Override
public void fill(long fromIndex, long toIndex, byte value) {
assert indexIsInt(fromIndex);
assert indexIsInt(toIndex);
Arrays.fill(array, (int) fromIndex, (int) toIndex, value);
}
@Override
public boolean hasArray() {
return true;
}
@Override
public byte[] array() {
return array;
}
@Override
public void writeTo(StreamOutput out) throws IOException {
int size = Math.toIntExact(size()) * Byte.BYTES;
out.writeVInt(size);
out.write(array, 0, size);
}
}
private static class ByteArrayAsIntArrayWrapper extends AbstractArrayWrapper implements IntArray {
final byte[] array;
ByteArrayAsIntArrayWrapper(BigArrays bigArrays, long size, boolean clearOnResize) {
super(bigArrays, size, null, clearOnResize);
assert size >= 0L && size <= PageCacheRecycler.INT_PAGE_SIZE;
this.array = new byte[(int) size << 2];
}
@Override
public void writeTo(StreamOutput out) throws IOException {
int intSize = (int) size();
out.writeVInt(intSize * 4);
out.write(array, 0, intSize * Integer.BYTES);
}
@Override
public long ramBytesUsed() {
return SHALLOW_SIZE + RamUsageEstimator.sizeOf(array);
}
@Override
public int get(long index) {
assert index >= 0 && index < size();
return (int) VH_PLATFORM_NATIVE_INT.get(array, (int) index << 2);
}
@Override
public int set(long index, int value) {
assert index >= 0 && index < size();
final int ret = (int) VH_PLATFORM_NATIVE_INT.get(array, (int) index << 2);
VH_PLATFORM_NATIVE_INT.set(array, (int) index << 2, value);
return ret;
}
@Override
public int increment(long index, int inc) {
assert index >= 0 && index < size();
final int ret = (int) VH_PLATFORM_NATIVE_INT.get(array, (int) index << 2) + inc;
VH_PLATFORM_NATIVE_INT.set(array, (int) index << 2, ret);
return ret;
}
@Override
public void fill(long fromIndex, long toIndex, int value) {
assert fromIndex >= 0 && fromIndex <= toIndex;
assert toIndex >= 0 && toIndex <= size();
BigIntArray.fill(array, (int) fromIndex, (int) toIndex, value);
}
@Override
public void set(long index, byte[] buf, int offset, int len) {
assert index >= 0 && index < size();
System.arraycopy(buf, offset << 2, array, (int) index << 2, len << 2);
}
}
private static class ByteArrayAsLongArrayWrapper extends AbstractArrayWrapper implements LongArray {
private final byte[] array;
ByteArrayAsLongArrayWrapper(BigArrays bigArrays, long size, boolean clearOnResize) {
super(bigArrays, size, null, clearOnResize);
assert size >= 0 && size <= PageCacheRecycler.LONG_PAGE_SIZE;
this.array = new byte[(int) size << 3];
}
@Override
public long ramBytesUsed() {
return SHALLOW_SIZE + RamUsageEstimator.sizeOf(array);
}
@Override
public long get(long index) {
assert index >= 0 && index < size();
return (long) VH_PLATFORM_NATIVE_LONG.get(array, (int) index << 3);
}
@Override
public long set(long index, long value) {
assert index >= 0 && index < size();
final long ret = (long) VH_PLATFORM_NATIVE_LONG.get(array, (int) index << 3);
VH_PLATFORM_NATIVE_LONG.set(array, (int) index << 3, value);
return ret;
}
@Override
public long increment(long index, long inc) {
assert index >= 0 && index < size();
final long ret = (long) VH_PLATFORM_NATIVE_LONG.get(array, (int) index << 3) + inc;
VH_PLATFORM_NATIVE_LONG.set(array, (int) index << 3, ret);
return ret;
}
@Override
public void fill(long fromIndex, long toIndex, long value) {
assert fromIndex >= 0 && fromIndex <= toIndex;
assert toIndex >= 0 && toIndex <= size();
BigLongArray.fill(array, (int) fromIndex, (int) toIndex, value);
}
@Override
public void set(long index, byte[] buf, int offset, int len) {
assert index >= 0 && index < size();
System.arraycopy(buf, offset << 3, array, (int) index << 3, len << 3);
}
@Override
public void writeTo(StreamOutput out) throws IOException {
int size = Math.toIntExact(size()) * Long.BYTES;
out.writeVInt(size);
out.write(array, 0, size);
}
}
private static class ByteArrayAsDoubleArrayWrapper extends AbstractArrayWrapper implements DoubleArray {
private final byte[] array;
ByteArrayAsDoubleArrayWrapper(BigArrays bigArrays, long size, boolean clearOnResize) {
super(bigArrays, size, null, clearOnResize);
assert size >= 0L && size <= PageCacheRecycler.DOUBLE_PAGE_SIZE;
this.array = new byte[(int) size << 3];
}
@Override
public long ramBytesUsed() {
return SHALLOW_SIZE + RamUsageEstimator.sizeOf(array);
}
@Override
public double get(long index) {
assert index >= 0 && index < size();
return (double) VH_PLATFORM_NATIVE_DOUBLE.get(array, (int) index << 3);
}
@Override
public double set(long index, double value) {
assert index >= 0 && index < size();
final double ret = (double) VH_PLATFORM_NATIVE_DOUBLE.get(array, (int) index << 3);
VH_PLATFORM_NATIVE_DOUBLE.set(array, (int) index << 3, value);
return ret;
}
@Override
public double increment(long index, double inc) {
assert index >= 0 && index < size();
final double ret = (double) VH_PLATFORM_NATIVE_DOUBLE.get(array, (int) index << 3) + inc;
VH_PLATFORM_NATIVE_DOUBLE.set(array, (int) index << 3, ret);
return ret;
}
@Override
public void fill(long fromIndex, long toIndex, double value) {
assert fromIndex >= 0 && fromIndex <= toIndex;
assert toIndex >= 0 && toIndex <= size();
BigDoubleArray.fill(array, (int) fromIndex, (int) toIndex, value);
}
@Override
public void set(long index, byte[] buf, int offset, int len) {
assert index >= 0 && index < size();
System.arraycopy(buf, offset << 3, array, (int) index << 3, len << 3);
}
@Override
public void writeTo(StreamOutput out) throws IOException {
int size = (int) size();
out.writeVInt(size * 8);
out.write(array, 0, size * Double.BYTES);
}
}
private static class ByteArrayAsFloatArrayWrapper extends AbstractArrayWrapper implements FloatArray {
private final byte[] array;
ByteArrayAsFloatArrayWrapper(BigArrays bigArrays, long size, boolean clearOnResize) {
super(bigArrays, size, null, clearOnResize);
assert size >= 0 && size <= PageCacheRecycler.FLOAT_PAGE_SIZE;
this.array = new byte[(int) size << 2];
}
@Override
public long ramBytesUsed() {
return SHALLOW_SIZE + RamUsageEstimator.sizeOf(array);
}
@Override
public float get(long index) {
assert index >= 0 && index < size();
return (float) VH_PLATFORM_NATIVE_FLOAT.get(array, (int) index << 2);
}
@Override
public float set(long index, float value) {
assert index >= 0 && index < size();
final float ret = (float) VH_PLATFORM_NATIVE_FLOAT.get(array, (int) index << 2);
VH_PLATFORM_NATIVE_FLOAT.set(array, (int) index << 2, value);
return ret;
}
@Override
public void fill(long fromIndex, long toIndex, float value) {
assert fromIndex >= 0 && fromIndex <= toIndex;
assert toIndex >= 0 && toIndex <= size();
BigFloatArray.fill(array, (int) fromIndex, (int) toIndex, value);
}
@Override
public void set(long index, byte[] buf, int offset, int len) {
assert index >= 0 && index < size();
System.arraycopy(buf, offset << 2, array, (int) index << 2, len << 2);
}
}
private static class ObjectArrayWrapper extends AbstractArrayWrapper implements ObjectArray {
private final Object[] array;
ObjectArrayWrapper(BigArrays bigArrays, Object[] array, long size, Recycler.V