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
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you 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 org.elasticsearch.common.util;
import com.google.common.base.Preconditions;
import org.apache.lucene.util.ArrayUtil;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.RamUsageEstimator;
import org.elasticsearch.cache.recycler.PageCacheRecycler;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.breaker.CircuitBreaker;
import org.elasticsearch.common.breaker.CircuitBreakingException;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.lease.Releasable;
import org.elasticsearch.common.lease.Releasables;
import org.elasticsearch.common.recycler.Recycler;
import org.elasticsearch.indices.breaker.CircuitBreakerService;
import java.util.Arrays;
/** Utility class to work with arrays. */
public class BigArrays {
public static final BigArrays NON_RECYCLING_INSTANCE = new BigArrays(null, null);
/** Page size in bytes: 16KB */
public static final int PAGE_SIZE_IN_BYTES = 1 << 14;
public static final int BYTE_PAGE_SIZE = BigArrays.PAGE_SIZE_IN_BYTES / RamUsageEstimator.NUM_BYTES_BYTE;
public static final int INT_PAGE_SIZE = BigArrays.PAGE_SIZE_IN_BYTES / RamUsageEstimator.NUM_BYTES_INT;
public static final int LONG_PAGE_SIZE = BigArrays.PAGE_SIZE_IN_BYTES / RamUsageEstimator.NUM_BYTES_LONG;
public static final int OBJECT_PAGE_SIZE = BigArrays.PAGE_SIZE_IN_BYTES / RamUsageEstimator.NUM_BYTES_OBJECT_REF;
/** 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, 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) {
Preconditions.checkArgument(minTargetSize >= 0, "minTargetSize must be >= 0");
Preconditions.checkArgument(pageSize >= 0, "pageSize must be > 0");
Preconditions.checkArgument(bytesPerElement > 0, "bytesPerElement must be > 0");
long newSize;
if (minTargetSize < pageSize) {
newSize = ArrayUtil.oversize((int)minTargetSize, bytesPerElement);
} else {
newSize = minTargetSize + (minTargetSize >>> 3);
}
if (newSize > pageSize) {
// round to a multiple of pageSize
newSize = newSize - (newSize % pageSize) + pageSize;
assert newSize % pageSize == 0;
}
return newSize;
}
static boolean indexIsInt(long index) {
return index == (int) index;
}
private static abstract class AbstractArrayWrapper extends AbstractArray implements BigArray {
protected 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);
}
}
private static class IntArrayWrapper extends AbstractArrayWrapper implements IntArray {
private final int[] array;
IntArrayWrapper(BigArrays bigArrays, int[] 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 int get(long index) {
assert indexIsInt(index);
return array[(int) index];
}
@Override
public int set(long index, int value) {
assert indexIsInt(index);
final int ret = array[(int) index];
array[(int) index] = value;
return ret;
}
@Override
public int increment(long index, int inc) {
assert indexIsInt(index);
return array[(int) index] += inc;
}
@Override
public void fill(long fromIndex, long toIndex, int value) {
assert indexIsInt(fromIndex);
assert indexIsInt(toIndex);
Arrays.fill(array, (int) fromIndex, (int) toIndex, value);
}
}
private static class LongArrayWrapper extends AbstractArrayWrapper implements LongArray {
private final long[] array;
LongArrayWrapper(BigArrays bigArrays, long[] 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 long get(long index) {
assert indexIsInt(index);
return array[(int) index];
}
@Override
public long set(long index, long value) {
assert indexIsInt(index);
final long ret = array[(int) index];
array[(int) index] = value;
return ret;
}
@Override
public long increment(long index, long inc) {
assert indexIsInt(index);
return array[(int) index] += inc;
}
@Override
public void fill(long fromIndex, long toIndex, long value) {
assert indexIsInt(fromIndex);
assert indexIsInt(toIndex);
Arrays.fill(array, (int) fromIndex, (int) toIndex, value);
}
}
private static class DoubleArrayWrapper extends AbstractArrayWrapper implements DoubleArray {
private final long[] array;
DoubleArrayWrapper(BigArrays bigArrays, long[] 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 double get(long index) {
assert indexIsInt(index);
return Double.longBitsToDouble(array[(int) index]);
}
@Override
public double set(long index, double value) {
assert indexIsInt(index);
double ret = Double.longBitsToDouble(array[(int) index]);
array[(int) index] = Double.doubleToRawLongBits(value);
return ret;
}
@Override
public double increment(long index, double inc) {
assert indexIsInt(index);
return array[(int) index] = Double.doubleToRawLongBits(Double.longBitsToDouble(array[(int) index]) + inc);
}
@Override
public void fill(long fromIndex, long toIndex, double value) {
assert indexIsInt(fromIndex);
assert indexIsInt(toIndex);
Arrays.fill(array, (int) fromIndex, (int) toIndex, Double.doubleToRawLongBits(value));
}
}
private static class FloatArrayWrapper extends AbstractArrayWrapper implements FloatArray {
private final int[] array;
FloatArrayWrapper(BigArrays bigArrays, int[] 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 float get(long index) {
assert indexIsInt(index);
return Float.intBitsToFloat(array[(int) index]);
}
@Override
public float set(long index, float value) {
assert indexIsInt(index);
float ret = Float.intBitsToFloat(array[(int) index]);
array[(int) index] = Float.floatToRawIntBits(value);
return ret;
}
@Override
public float increment(long index, float inc) {
assert indexIsInt(index);
return array[(int) index] = Float.floatToRawIntBits(Float.intBitsToFloat(array[(int) index]) + inc);
}
@Override
public void fill(long fromIndex, long toIndex, float value) {
assert indexIsInt(fromIndex);
assert indexIsInt(toIndex);
Arrays.fill(array, (int) fromIndex, (int) toIndex, Float.floatToRawIntBits(value));
}
}
private static class ObjectArrayWrapper extends AbstractArrayWrapper implements ObjectArray {
private final Object[] array;
ObjectArrayWrapper(BigArrays bigArrays, Object[] array, long size, Recycler.V