Skip to content

Commit

Permalink
Reuse pages more agressively in BigArrays.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
jpountz committed Feb 28, 2014
1 parent 70e7397 commit ee490c1
Showing 1 changed file with 79 additions and 65 deletions.
144 changes: 79 additions & 65 deletions src/main/java/org/elasticsearch/common/util/BigArrays.java
Expand Up @@ -26,6 +26,9 @@
import org.elasticsearch.cache.recycler.PageCacheRecycler;
import org.elasticsearch.common.component.AbstractComponent;
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.Settings;

Expand Down Expand Up @@ -77,18 +80,36 @@ static boolean indexIsInt(long 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);
this.array = array;
this.releasable = releasable;
this.size = size;
}

public final long size() {
return size;
}

@Override
public long size() {
return array.length;
public final boolean release() {
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
Expand Down Expand Up @@ -121,20 +142,15 @@ public void set(long index, byte[] buf, int offset, int len) {

}

private static class IntArrayWrapper extends AbstractArray implements IntArray {
private static class IntArrayWrapper extends AbstractArrayWrapper implements IntArray {

private final int[] array;

IntArrayWrapper(int[] array, PageCacheRecycler recycler, boolean clearOnResize) {
super(clearOnResize);
IntArrayWrapper(int[] array, long size, Recycler.V<int[]> releasable, boolean clearOnResize) {
super(size, releasable, clearOnResize);
this.array = array;
}

@Override
public long size() {
return array.length;
}

@Override
public int get(long index) {
assert indexIsInt(index);
Expand All @@ -157,20 +173,15 @@ public int increment(long index, int inc) {

}

private static class LongArrayWrapper extends AbstractArray implements LongArray {
private static class LongArrayWrapper extends AbstractArrayWrapper implements LongArray {

private final long[] array;

LongArrayWrapper(long[] array, PageCacheRecycler recycler, boolean clearOnResize) {
super(clearOnResize);
LongArrayWrapper(long[] array, long size, Recycler.V<long[]> releasable, boolean clearOnResize) {
super(size, releasable, clearOnResize);
this.array = array;
}

@Override
public long size() {
return array.length;
}

@Override
public long get(long index) {
assert indexIsInt(index);
Expand Down Expand Up @@ -199,20 +210,15 @@ public void fill(long fromIndex, long toIndex, long value) {
}
}

private static class DoubleArrayWrapper extends AbstractArray implements DoubleArray {
private static class DoubleArrayWrapper extends AbstractArrayWrapper implements DoubleArray {

private final double[] array;

DoubleArrayWrapper(double[] array, PageCacheRecycler recycler, boolean clearOnResize) {
super(clearOnResize);
DoubleArrayWrapper(double[] array, long size, Recycler.V<double[]> releasable, boolean clearOnResize) {
super(size, releasable, clearOnResize);
this.array = array;
}

@Override
public long size() {
return array.length;
}

@Override
public double get(long index) {
assert indexIsInt(index);
Expand Down Expand Up @@ -242,20 +248,15 @@ public void fill(long fromIndex, long toIndex, double value) {

}

private static class FloatArrayWrapper extends AbstractArray implements FloatArray {
private static class FloatArrayWrapper extends AbstractArrayWrapper implements FloatArray {

private final float[] array;

FloatArrayWrapper(float[] array, PageCacheRecycler recycler, boolean clearOnResize) {
super(clearOnResize);
FloatArrayWrapper(float[] array, long size, Recycler.V<float[]> releasable, boolean clearOnResize) {
super(size, releasable, clearOnResize);
this.array = array;
}

@Override
public long size() {
return array.length;
}

@Override
public float get(long index) {
assert indexIsInt(index);
Expand Down Expand Up @@ -285,20 +286,15 @@ public void fill(long fromIndex, long toIndex, float value) {

}

private static class ObjectArrayWrapper<T> extends AbstractArray implements ObjectArray<T> {
private static class ObjectArrayWrapper<T> extends AbstractArrayWrapper implements ObjectArray<T> {

private final Object[] array;

ObjectArrayWrapper(Object[] array, PageCacheRecycler recycler) {
super(true);
ObjectArrayWrapper(Object[] array, long size, Recycler.V<Object[]> releasable) {
super(size, releasable, true);
this.array = array;
}

@Override
public long size() {
return array.length;
}

@SuppressWarnings("unchecked")
@Override
public T get(long index) {
Expand All @@ -317,7 +313,7 @@ public T set(long index, T value) {

}

private final PageCacheRecycler recycler;
final PageCacheRecycler recycler;

@Inject
public BigArrays(Settings settings, PageCacheRecycler recycler) {
Expand All @@ -331,10 +327,13 @@ public BigArrays(Settings settings, PageCacheRecycler recycler) {
* @param clearOnResize whether values should be set to 0 on initialization and resize
*/
public ByteArray newByteArray(long size, boolean clearOnResize) {
if (size <= BYTE_PAGE_SIZE) {
return new ByteArrayWrapper(new byte[(int) size], recycler, clearOnResize);
} else {
if (size > BYTE_PAGE_SIZE) {
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);
}
}

Expand Down Expand Up @@ -376,10 +375,13 @@ public ByteArray grow(ByteArray array, long minSize) {
* @param clearOnResize whether values should be set to 0 on initialization and resize
*/
public IntArray newIntArray(long size, boolean clearOnResize) {
if (size <= INT_PAGE_SIZE) {
return new IntArrayWrapper(new int[(int) size], recycler, clearOnResize);
} else {
if (size > INT_PAGE_SIZE) {
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);
}
}

Expand Down Expand Up @@ -422,10 +424,13 @@ public IntArray grow(IntArray array, long minSize) {
* @param clearOnResize whether values should be set to 0 on initialization and resize
*/
public LongArray newLongArray(long size, boolean clearOnResize) {
if (size <= LONG_PAGE_SIZE) {
return new LongArrayWrapper(new long[(int) size], recycler, clearOnResize);
} else {
if (size > LONG_PAGE_SIZE) {
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);
}
}

Expand Down Expand Up @@ -468,10 +473,13 @@ public LongArray grow(LongArray array, long minSize) {
* @param clearOnResize whether values should be set to 0 on initialization and resize
*/
public DoubleArray newDoubleArray(long size, boolean clearOnResize) {
if (size <= LONG_PAGE_SIZE) {
return new DoubleArrayWrapper(new double[(int) size], recycler, clearOnResize);
} else {
if (size > DOUBLE_PAGE_SIZE) {
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);
}
}

Expand Down Expand Up @@ -511,10 +519,13 @@ public DoubleArray grow(DoubleArray array, long minSize) {
* @param clearOnResize whether values should be set to 0 on initialization and resize
*/
public FloatArray newFloatArray(long size, boolean clearOnResize) {
if (size <= FLOAT_PAGE_SIZE) {
return new FloatArrayWrapper(new float[(int) size], recycler, clearOnResize);
} else {
if (size > FLOAT_PAGE_SIZE) {
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);
}
}

Expand Down Expand Up @@ -552,10 +563,13 @@ public FloatArray grow(FloatArray array, long minSize) {
* @param size the initial length of the array
*/
public <T> ObjectArray<T> newObjectArray(long size) {
if (size <= OBJECT_PAGE_SIZE) {
return new ObjectArrayWrapper<T>(new Object[(int) size], recycler);
} else {
if (size > OBJECT_PAGE_SIZE) {
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);
}
}

Expand Down

0 comments on commit ee490c1

Please sign in to comment.