From 5a6238ed4c1f9c81de5cb0e9106e886420eb97a0 Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Fri, 16 Oct 2015 13:20:51 +0200 Subject: [PATCH] Minimize reference count checks in SlicedByteBuf Motivation: SlicedByteBuf did double reference count checking for various bulk operations, which affects performance. Modifications: - Add package private method to AbstractByteBuf that can be used to check indexes without check the reference count - Use this new method in the bulk operation os SlicedByteBuf as the reference count checks take place on the wrapped buffer anyway - Fix test-case to not try to read data that is out of the bounds of the buffer. Result: Better performance on bulk operations when using SlicedByteBuf (and sub-classes) --- .../java/io/netty/buffer/AbstractByteBuf.java | 4 +++ .../java/io/netty/buffer/SlicedByteBuf.java | 31 ++++++++++--------- .../io/netty/buffer/AbstractByteBufTest.java | 2 +- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/buffer/src/main/java/io/netty/buffer/AbstractByteBuf.java b/buffer/src/main/java/io/netty/buffer/AbstractByteBuf.java index fb9ad6dba7..0e29175c35 100644 --- a/buffer/src/main/java/io/netty/buffer/AbstractByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/AbstractByteBuf.java @@ -1106,6 +1106,10 @@ public abstract class AbstractByteBuf extends ByteBuf { protected final void checkIndex(int index, int fieldLength) { ensureAccessible(); + checkIndex0(index, fieldLength); + } + + final void checkIndex0(int index, int fieldLength) { if (isInvalid(index, fieldLength, capacity())) { throw new IndexOutOfBoundsException(String.format( "index: %d, length: %d (expected: range(0, %d))", index, fieldLength, capacity())); diff --git a/buffer/src/main/java/io/netty/buffer/SlicedByteBuf.java b/buffer/src/main/java/io/netty/buffer/SlicedByteBuf.java index 8784f3fbbc..78db1eb9b8 100644 --- a/buffer/src/main/java/io/netty/buffer/SlicedByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/SlicedByteBuf.java @@ -148,33 +148,33 @@ public class SlicedByteBuf extends AbstractDerivedByteBuf { @Override public ByteBuf copy(int index, int length) { - checkIndex(index, length); + checkIndex0(index, length); return buffer.copy(idx(index), length); } @Override public ByteBuf slice(int index, int length) { - checkIndex(index, length); + checkIndex0(index, length); return buffer.slice(idx(index), length); } @Override public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) { - checkIndex(index, length); + checkIndex0(index, length); buffer.getBytes(idx(index), dst, dstIndex, length); return this; } @Override public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { - checkIndex(index, length); + checkIndex0(index, length); buffer.getBytes(idx(index), dst, dstIndex, length); return this; } @Override public ByteBuf getBytes(int index, ByteBuffer dst) { - checkIndex(index, dst.remaining()); + checkIndex0(index, dst.remaining()); buffer.getBytes(idx(index), dst); return this; } @@ -206,47 +206,47 @@ public class SlicedByteBuf extends AbstractDerivedByteBuf { @Override public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) { - checkIndex(index, length); + checkIndex0(index, length); buffer.setBytes(idx(index), src, srcIndex, length); return this; } @Override public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) { - checkIndex(index, length); + checkIndex0(index, length); buffer.setBytes(idx(index), src, srcIndex, length); return this; } @Override public ByteBuf setBytes(int index, ByteBuffer src) { - checkIndex(index, src.remaining()); + checkIndex0(index, src.remaining()); buffer.setBytes(idx(index), src); return this; } @Override public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException { - checkIndex(index, length); + checkIndex0(index, length); buffer.getBytes(idx(index), out, length); return this; } @Override public int getBytes(int index, GatheringByteChannel out, int length) throws IOException { - checkIndex(index, length); + checkIndex0(index, length); return buffer.getBytes(idx(index), out, length); } @Override public int setBytes(int index, InputStream in, int length) throws IOException { - checkIndex(index, length); + checkIndex0(index, length); return buffer.setBytes(idx(index), in, length); } @Override public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException { - checkIndex(index, length); + checkIndex0(index, length); return buffer.setBytes(idx(index), in, length); } @@ -257,24 +257,24 @@ public class SlicedByteBuf extends AbstractDerivedByteBuf { @Override public ByteBuffer nioBuffer(int index, int length) { - checkIndex(index, length); + checkIndex0(index, length); return buffer.nioBuffer(idx(index), length); } @Override public ByteBuffer[] nioBuffers(int index, int length) { - checkIndex(index, length); + checkIndex0(index, length); return buffer.nioBuffers(idx(index), length); } @Override public ByteBuffer internalNioBuffer(int index, int length) { - checkIndex(index, length); return nioBuffer(index, length); } @Override public int forEachByte(int index, int length, ByteProcessor processor) { + checkIndex0(index, length); int ret = buffer.forEachByte(idx(index), length, processor); if (ret >= adjustment) { return ret - adjustment; @@ -285,6 +285,7 @@ public class SlicedByteBuf extends AbstractDerivedByteBuf { @Override public int forEachByteDesc(int index, int length, ByteProcessor processor) { + checkIndex0(index, length); int ret = buffer.forEachByteDesc(idx(index), length, processor); if (ret >= adjustment) { return ret - adjustment; diff --git a/buffer/src/test/java/io/netty/buffer/AbstractByteBufTest.java b/buffer/src/test/java/io/netty/buffer/AbstractByteBufTest.java index 80405a6a0a..a9d7955909 100644 --- a/buffer/src/test/java/io/netty/buffer/AbstractByteBufTest.java +++ b/buffer/src/test/java/io/netty/buffer/AbstractByteBufTest.java @@ -2043,7 +2043,7 @@ public abstract class AbstractByteBufTest { @Test(expected = IllegalReferenceCountException.class) public void testGetBytesAfterRelease() { - releasedBuffer().getBytes(0, releaseLater(buffer())); + releasedBuffer().getBytes(0, releaseLater(buffer(8))); } @Test(expected = IllegalReferenceCountException.class)