No need to do a memory copy to verify snappy identifier

Motivation:

We are currently doing a memory copy to verify the snapy version. This is not needed.

Modifications:

Remove memory copy and just compare byte per byte.

Result:

Less memory copies and allocations
This commit is contained in:
Norman Maurer 2016-07-20 07:14:59 +02:00
parent 9c0d1a99bc
commit f25f1f255d

View File

@ -19,7 +19,6 @@ import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder; import io.netty.handler.codec.ByteToMessageDecoder;
import java.util.Arrays;
import java.util.List; import java.util.List;
import static io.netty.handler.codec.compression.Snappy.validateChecksum; import static io.netty.handler.codec.compression.Snappy.validateChecksum;
@ -45,7 +44,7 @@ public class SnappyFrameDecoder extends ByteToMessageDecoder {
RESERVED_SKIPPABLE RESERVED_SKIPPABLE
} }
private static final byte[] SNAPPY = { 's', 'N', 'a', 'P', 'p', 'Y' }; private static final int SNAPPY_IDENTIFIER_LEN = 6;
private static final int MAX_UNCOMPRESSED_DATA_SIZE = 65536 + 4; private static final int MAX_UNCOMPRESSED_DATA_SIZE = 65536 + 4;
private final Snappy snappy = new Snappy(); private final Snappy snappy = new Snappy();
@ -98,21 +97,24 @@ public class SnappyFrameDecoder extends ByteToMessageDecoder {
switch (chunkType) { switch (chunkType) {
case STREAM_IDENTIFIER: case STREAM_IDENTIFIER:
if (chunkLength != SNAPPY.length) { if (chunkLength != SNAPPY_IDENTIFIER_LEN) {
throw new DecompressionException("Unexpected length of stream identifier: " + chunkLength); throw new DecompressionException("Unexpected length of stream identifier: " + chunkLength);
} }
if (inSize < 4 + SNAPPY.length) { if (inSize < 4 + SNAPPY_IDENTIFIER_LEN) {
break; break;
} }
byte[] identifier = new byte[chunkLength]; in.skipBytes(4);
in.skipBytes(4).readBytes(identifier); int offset = in.readerIndex();
in.skipBytes(SNAPPY_IDENTIFIER_LEN);
if (!Arrays.equals(identifier, SNAPPY)) { checkByte(in.getByte(offset++), (byte) 's');
throw new DecompressionException("Unexpected stream identifier contents. Mismatched snappy " + checkByte(in.getByte(offset++), (byte) 'N');
"protocol version?"); checkByte(in.getByte(offset++), (byte) 'a');
} checkByte(in.getByte(offset++), (byte) 'P');
checkByte(in.getByte(offset++), (byte) 'p');
checkByte(in.getByte(offset), (byte) 'Y');
started = true; started = true;
break; break;
@ -196,6 +198,13 @@ public class SnappyFrameDecoder extends ByteToMessageDecoder {
} }
} }
private static void checkByte(byte actual, byte expect) {
if (actual != expect) {
throw new DecompressionException("Unexpected stream identifier contents. Mismatched snappy " +
"protocol version?");
}
}
/** /**
* Decodes the chunk type from the type tag byte. * Decodes the chunk type from the type tag byte.
* *