[#2168] Eliminate unnessary memory copy for heap buffers in JdkZlibEncoder

* Also adjust tests so it test with direct and heap buffers
This commit is contained in:
Norman Maurer 2014-01-30 06:29:52 +01:00
parent 37e6588845
commit 0f7379157a
2 changed files with 24 additions and 9 deletions

View File

@ -196,8 +196,20 @@ public class JdkZlibEncoder extends ZlibEncoder {
return;
}
byte[] inAry = new byte[uncompressed.readableBytes()];
int len = uncompressed.readableBytes();
int offset;
byte[] inAry;
if (uncompressed.hasArray()) {
// if it is backed by an array we not need to to do a copy at all
inAry = uncompressed.array();
offset = uncompressed.arrayOffset() + uncompressed.readerIndex();
// skip all bytes as we will consume all of them
uncompressed.skipBytes(len);
} else {
inAry = new byte[len];
uncompressed.readBytes(inAry);
offset = 0;
}
int sizeEstimate = (int) Math.ceil(inAry.length * 1.001) + 12;
@ -222,7 +234,7 @@ public class JdkZlibEncoder extends ZlibEncoder {
crc.update(inAry);
}
deflater.setInput(inAry);
deflater.setInput(inAry, offset, len);
while (!deflater.needsInput()) {
deflate(out);
}

View File

@ -58,8 +58,7 @@ public abstract class ZlibTest {
buf.release();
}
private void testCompress0(ZlibWrapper encoderWrapper, ZlibWrapper decoderWrapper, byte[] bytes) throws Exception {
ByteBuf data = Unpooled.wrappedBuffer(bytes);
private void testCompress0(ZlibWrapper encoderWrapper, ZlibWrapper decoderWrapper, ByteBuf data) throws Exception {
EmbeddedChannel chEncoder = new EmbeddedChannel(createEncoder(encoderWrapper));
chEncoder.writeOutbound(data.copy());
@ -74,7 +73,7 @@ public abstract class ZlibTest {
chDecoderZlib.writeInbound(deflatedData);
}
byte[] decompressed = new byte[bytes.length];
byte[] decompressed = new byte[data.readableBytes()];
int offset = 0;
for (;;) {
ByteBuf buf = (ByteBuf) chDecoderZlib.readInbound();
@ -89,7 +88,7 @@ public abstract class ZlibTest {
break;
}
}
assertArrayEquals(bytes, decompressed);
assertEquals(data, Unpooled.wrappedBuffer(decompressed));
assertNull(chDecoderZlib.readInbound());
// Closing an encoder channel will generate a footer.
@ -137,11 +136,15 @@ public abstract class ZlibTest {
}
private void testCompressSmall(ZlibWrapper encoderWrapper, ZlibWrapper decoderWrapper) throws Exception {
testCompress0(encoderWrapper, decoderWrapper, BYTES_SMALL);
testCompress0(encoderWrapper, decoderWrapper, Unpooled.wrappedBuffer(BYTES_SMALL));
testCompress0(encoderWrapper, decoderWrapper,
Unpooled.directBuffer(BYTES_SMALL.length).writeBytes(BYTES_SMALL));
}
private void testCompressLarge(ZlibWrapper encoderWrapper, ZlibWrapper decoderWrapper) throws Exception {
testCompress0(encoderWrapper, decoderWrapper, BYTES_LARGE);
testCompress0(encoderWrapper, decoderWrapper, Unpooled.wrappedBuffer(BYTES_LARGE));
testCompress0(encoderWrapper, decoderWrapper,
Unpooled.directBuffer(BYTES_LARGE.length).writeBytes(BYTES_LARGE));
}
@Test