BytesStreamOutput default size should be 2k instead of 32k
We changed the default of BytesStreamOutput (used in various places in ES) to 32k from 1k with the assumption that most stream tend to be large. This doesn't hold for example when indexing small documents and adding them using XContentBuilder (which will have a large overhead). Default the buffer size to 2k now, but be relatively aggressive in expanding the buffer when below 256k (double it), and just use oversize (1/8th) when larger to try and minimize garbage and buffer copies. relates to #3624 closes #3638
This commit is contained in:
parent
3e92b1d6b8
commit
4155741f7f
|
@ -31,7 +31,9 @@ import java.io.IOException;
|
|||
*/
|
||||
public class BytesStreamOutput extends StreamOutput implements BytesStream {
|
||||
|
||||
public static final int DEFAULT_SIZE = 32 * 1024;
|
||||
public static final int DEFAULT_SIZE = 2 * 1024;
|
||||
|
||||
public static final int OVERSIZE_LIMIT = 256 * 1024;
|
||||
|
||||
/**
|
||||
* The buffer where data is stored.
|
||||
|
@ -73,7 +75,7 @@ public class BytesStreamOutput extends StreamOutput implements BytesStream {
|
|||
public void writeByte(byte b) throws IOException {
|
||||
int newcount = count + 1;
|
||||
if (newcount > buf.length) {
|
||||
buf = ArrayUtil.grow(buf, newcount);
|
||||
buf = grow(newcount);
|
||||
}
|
||||
buf[count] = b;
|
||||
count = newcount;
|
||||
|
@ -82,7 +84,7 @@ public class BytesStreamOutput extends StreamOutput implements BytesStream {
|
|||
public void skip(int length) {
|
||||
int newcount = count + length;
|
||||
if (newcount > buf.length) {
|
||||
buf = ArrayUtil.grow(buf, newcount);
|
||||
buf = grow(newcount);
|
||||
}
|
||||
count = newcount;
|
||||
}
|
||||
|
@ -94,12 +96,20 @@ public class BytesStreamOutput extends StreamOutput implements BytesStream {
|
|||
}
|
||||
int newcount = count + length;
|
||||
if (newcount > buf.length) {
|
||||
buf = ArrayUtil.grow(buf, newcount);
|
||||
buf = grow(newcount);
|
||||
}
|
||||
System.arraycopy(b, offset, buf, count, length);
|
||||
count = newcount;
|
||||
}
|
||||
|
||||
private byte[] grow(int newCount) {
|
||||
// try and grow faster while we are small...
|
||||
if (newCount < OVERSIZE_LIMIT) {
|
||||
newCount = Math.max(buf.length << 1, newCount);
|
||||
}
|
||||
return ArrayUtil.grow(buf, newCount);
|
||||
}
|
||||
|
||||
public void seek(int seekTo) {
|
||||
count = seekTo;
|
||||
}
|
||||
|
@ -108,6 +118,10 @@ public class BytesStreamOutput extends StreamOutput implements BytesStream {
|
|||
count = 0;
|
||||
}
|
||||
|
||||
public int bufferSize() {
|
||||
return buf.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
// nothing to do there
|
||||
|
|
|
@ -60,4 +60,17 @@ public class BytesStreamsTests {
|
|||
assertThat(in.readString(), equalTo("hello"));
|
||||
assertThat(in.readString(), equalTo("goodbye"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrowLogic() throws Exception {
|
||||
BytesStreamOutput out = new BytesStreamOutput();
|
||||
out.writeBytes(new byte[BytesStreamOutput.DEFAULT_SIZE - 5]);
|
||||
assertThat(out.bufferSize(), equalTo(2048)); // remains the default
|
||||
out.writeBytes(new byte[1 * 1024]);
|
||||
assertThat(out.bufferSize(), equalTo(4608));
|
||||
out.writeBytes(new byte[32 * 1024]);
|
||||
assertThat(out.bufferSize(), equalTo(40320));
|
||||
out.writeBytes(new byte[32 * 1024]);
|
||||
assertThat(out.bufferSize(), equalTo(90720));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue