Reuse pages more agressively in BigArrays.

Pages are now going to be reused when the size of the array is greater than
${page_size}/2 (as opposed to ${page_size} currently).

Close #5299
This commit is contained in:
Adrien Grand 2014-02-28 16:39:51 +01:00
parent 5723603987
commit 2c5d77cde1
1 changed files with 79 additions and 65 deletions

View File

@ -26,6 +26,9 @@ import org.apache.lucene.util.RamUsageEstimator;
import org.elasticsearch.cache.recycler.PageCacheRecycler; import org.elasticsearch.cache.recycler.PageCacheRecycler;
import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.inject.Inject; 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.common.settings.ImmutableSettings; import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
@ -77,18 +80,36 @@ public class BigArrays extends AbstractComponent {
return index == (int) index; return index == (int) index;
} }
private static class ByteArrayWrapper extends AbstractArray implements ByteArray { private static abstract class AbstractArrayWrapper extends AbstractArray {
private final byte[] array; private final Releasable releasable;
private final long size;
ByteArrayWrapper(byte[] array, PageCacheRecycler recycler, boolean clearOnResize) { AbstractArrayWrapper(long size, Releasable releasable, boolean clearOnResize) {
super(clearOnResize); super(clearOnResize);
this.array = array; this.releasable = releasable;
this.size = size;
}
public final long size() {
return size;
} }
@Override @Override
public long size() { public final boolean release() {
return array.length; Releasables.release(releasable);
return true;
}
}
private static class ByteArrayWrapper extends AbstractArrayWrapper implements ByteArray {
private final byte[] array;
ByteArrayWrapper(byte[] array, long size, Recycler.V<byte[]> releasable, boolean clearOnResize) {
super(size, releasable, clearOnResize);
this.array = array;
} }
@Override @Override
@ -121,20 +142,15 @@ public class BigArrays extends AbstractComponent {
} }
private static class IntArrayWrapper extends AbstractArray implements IntArray { private static class IntArrayWrapper extends AbstractArrayWrapper implements IntArray {
private final int[] array; private final int[] array;
IntArrayWrapper(int[] array, PageCacheRecycler recycler, boolean clearOnResize) { IntArrayWrapper(int[] array, long size, Recycler.V<int[]> releasable, boolean clearOnResize) {
super(clearOnResize); super(size, releasable, clearOnResize);
this.array = array; this.array = array;
} }
@Override
public long size() {
return array.length;
}
@Override @Override
public int get(long index) { public int get(long index) {
assert indexIsInt(index); assert indexIsInt(index);
@ -157,20 +173,15 @@ public class BigArrays extends AbstractComponent {
} }
private static class LongArrayWrapper extends AbstractArray implements LongArray { private static class LongArrayWrapper extends AbstractArrayWrapper implements LongArray {
private final long[] array; private final long[] array;
LongArrayWrapper(long[] array, PageCacheRecycler recycler, boolean clearOnResize) { LongArrayWrapper(long[] array, long size, Recycler.V<long[]> releasable, boolean clearOnResize) {
super(clearOnResize); super(size, releasable, clearOnResize);
this.array = array; this.array = array;
} }
@Override
public long size() {
return array.length;
}
@Override @Override
public long get(long index) { public long get(long index) {
assert indexIsInt(index); assert indexIsInt(index);
@ -199,20 +210,15 @@ public class BigArrays extends AbstractComponent {
} }
} }
private static class DoubleArrayWrapper extends AbstractArray implements DoubleArray { private static class DoubleArrayWrapper extends AbstractArrayWrapper implements DoubleArray {
private final double[] array; private final double[] array;
DoubleArrayWrapper(double[] array, PageCacheRecycler recycler, boolean clearOnResize) { DoubleArrayWrapper(double[] array, long size, Recycler.V<double[]> releasable, boolean clearOnResize) {
super(clearOnResize); super(size, releasable, clearOnResize);
this.array = array; this.array = array;
} }
@Override
public long size() {
return array.length;
}
@Override @Override
public double get(long index) { public double get(long index) {
assert indexIsInt(index); assert indexIsInt(index);
@ -242,20 +248,15 @@ public class BigArrays extends AbstractComponent {
} }
private static class FloatArrayWrapper extends AbstractArray implements FloatArray { private static class FloatArrayWrapper extends AbstractArrayWrapper implements FloatArray {
private final float[] array; private final float[] array;
FloatArrayWrapper(float[] array, PageCacheRecycler recycler, boolean clearOnResize) { FloatArrayWrapper(float[] array, long size, Recycler.V<float[]> releasable, boolean clearOnResize) {
super(clearOnResize); super(size, releasable, clearOnResize);
this.array = array; this.array = array;
} }
@Override
public long size() {
return array.length;
}
@Override @Override
public float get(long index) { public float get(long index) {
assert indexIsInt(index); assert indexIsInt(index);
@ -285,20 +286,15 @@ public class BigArrays extends AbstractComponent {
} }
private static class ObjectArrayWrapper<T> extends AbstractArray implements ObjectArray<T> { private static class ObjectArrayWrapper<T> extends AbstractArrayWrapper implements ObjectArray<T> {
private final Object[] array; private final Object[] array;
ObjectArrayWrapper(Object[] array, PageCacheRecycler recycler) { ObjectArrayWrapper(Object[] array, long size, Recycler.V<Object[]> releasable) {
super(true); super(size, releasable, true);
this.array = array; this.array = array;
} }
@Override
public long size() {
return array.length;
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public T get(long index) { public T get(long index) {
@ -317,7 +313,7 @@ public class BigArrays extends AbstractComponent {
} }
private final PageCacheRecycler recycler; final PageCacheRecycler recycler;
@Inject @Inject
public BigArrays(Settings settings, PageCacheRecycler recycler) { public BigArrays(Settings settings, PageCacheRecycler recycler) {
@ -331,10 +327,13 @@ public class BigArrays extends AbstractComponent {
* @param clearOnResize whether values should be set to 0 on initialization and resize * @param clearOnResize whether values should be set to 0 on initialization and resize
*/ */
public ByteArray newByteArray(long size, boolean clearOnResize) { public ByteArray newByteArray(long size, boolean clearOnResize) {
if (size <= BYTE_PAGE_SIZE) { if (size > BYTE_PAGE_SIZE) {
return new ByteArrayWrapper(new byte[(int) size], recycler, clearOnResize);
} else {
return new BigByteArray(size, recycler, clearOnResize); return new BigByteArray(size, recycler, clearOnResize);
} else if (size >= BYTE_PAGE_SIZE / 2 && recycler != null) {
final Recycler.V<byte[]> page = recycler.bytePage(clearOnResize);
return new ByteArrayWrapper(page.v(), size, page, clearOnResize);
} else {
return new ByteArrayWrapper(new byte[(int) size], size, null, clearOnResize);
} }
} }
@ -376,10 +375,13 @@ public class BigArrays extends AbstractComponent {
* @param clearOnResize whether values should be set to 0 on initialization and resize * @param clearOnResize whether values should be set to 0 on initialization and resize
*/ */
public IntArray newIntArray(long size, boolean clearOnResize) { public IntArray newIntArray(long size, boolean clearOnResize) {
if (size <= INT_PAGE_SIZE) { if (size > INT_PAGE_SIZE) {
return new IntArrayWrapper(new int[(int) size], recycler, clearOnResize);
} else {
return new BigIntArray(size, recycler, clearOnResize); return new BigIntArray(size, recycler, clearOnResize);
} else if (size >= INT_PAGE_SIZE / 2 && recycler != null) {
final Recycler.V<int[]> page = recycler.intPage(clearOnResize);
return new IntArrayWrapper(page.v(), size, page, clearOnResize);
} else {
return new IntArrayWrapper(new int[(int) size], size, null, clearOnResize);
} }
} }
@ -422,10 +424,13 @@ public class BigArrays extends AbstractComponent {
* @param clearOnResize whether values should be set to 0 on initialization and resize * @param clearOnResize whether values should be set to 0 on initialization and resize
*/ */
public LongArray newLongArray(long size, boolean clearOnResize) { public LongArray newLongArray(long size, boolean clearOnResize) {
if (size <= LONG_PAGE_SIZE) { if (size > LONG_PAGE_SIZE) {
return new LongArrayWrapper(new long[(int) size], recycler, clearOnResize);
} else {
return new BigLongArray(size, recycler, clearOnResize); return new BigLongArray(size, recycler, clearOnResize);
} else if (size >= LONG_PAGE_SIZE / 2 && recycler != null) {
final Recycler.V<long[]> page = recycler.longPage(clearOnResize);
return new LongArrayWrapper(page.v(), size, page, clearOnResize);
} else {
return new LongArrayWrapper(new long[(int) size], size, null, clearOnResize);
} }
} }
@ -468,10 +473,13 @@ public class BigArrays extends AbstractComponent {
* @param clearOnResize whether values should be set to 0 on initialization and resize * @param clearOnResize whether values should be set to 0 on initialization and resize
*/ */
public DoubleArray newDoubleArray(long size, boolean clearOnResize) { public DoubleArray newDoubleArray(long size, boolean clearOnResize) {
if (size <= LONG_PAGE_SIZE) { if (size > DOUBLE_PAGE_SIZE) {
return new DoubleArrayWrapper(new double[(int) size], recycler, clearOnResize);
} else {
return new BigDoubleArray(size, recycler, clearOnResize); return new BigDoubleArray(size, recycler, clearOnResize);
} else if (size >= DOUBLE_PAGE_SIZE / 2 && recycler != null) {
final Recycler.V<double[]> page = recycler.doublePage(clearOnResize);
return new DoubleArrayWrapper(page.v(), size, page, clearOnResize);
} else {
return new DoubleArrayWrapper(new double[(int) size], size, null, clearOnResize);
} }
} }
@ -511,10 +519,13 @@ public class BigArrays extends AbstractComponent {
* @param clearOnResize whether values should be set to 0 on initialization and resize * @param clearOnResize whether values should be set to 0 on initialization and resize
*/ */
public FloatArray newFloatArray(long size, boolean clearOnResize) { public FloatArray newFloatArray(long size, boolean clearOnResize) {
if (size <= FLOAT_PAGE_SIZE) { if (size > FLOAT_PAGE_SIZE) {
return new FloatArrayWrapper(new float[(int) size], recycler, clearOnResize);
} else {
return new BigFloatArray(size, recycler, clearOnResize); return new BigFloatArray(size, recycler, clearOnResize);
} else if (size >= FLOAT_PAGE_SIZE / 2 && recycler != null) {
final Recycler.V<float[]> page = recycler.floatPage(clearOnResize);
return new FloatArrayWrapper(page.v(), size, page, clearOnResize);
} else {
return new FloatArrayWrapper(new float[(int) size], size, null, clearOnResize);
} }
} }
@ -552,10 +563,13 @@ public class BigArrays extends AbstractComponent {
* @param size the initial length of the array * @param size the initial length of the array
*/ */
public <T> ObjectArray<T> newObjectArray(long size) { public <T> ObjectArray<T> newObjectArray(long size) {
if (size <= OBJECT_PAGE_SIZE) { if (size > OBJECT_PAGE_SIZE) {
return new ObjectArrayWrapper<T>(new Object[(int) size], recycler);
} else {
return new BigObjectArray<T>(size, recycler); return new BigObjectArray<T>(size, recycler);
} else if (size >= OBJECT_PAGE_SIZE / 2 && recycler != null) {
final Recycler.V<Object[]> page = recycler.objectPage();
return new ObjectArrayWrapper<T>(page.v(), size, page);
} else {
return new ObjectArrayWrapper<T>(new Object[(int) size], size, null);
} }
} }