Remove unnecessary loop and indentation in decompressors
Motivation: Decompression handlers contain heavy use of switch-case statements. We use compact indentation style for 'case' so that we utilize our screen real-estate more efficiently. Also, the following decompression handlers do not need to run a loop, because ByteToMessageDecoder already runs a loop for them: - FastLzFrameDecoder - Lz4FrameDecoder - LzfDecoder Modifications: - Fix indentations - Do not wrap the decoding logic with a for loop when unnecessary - Handle the case where a FastLz/Lzf frame contains no data properly so that the buffer does not leak and less garbage is produced. Result: - Efficiency - Compact source code - No buffer leak
This commit is contained in:
parent
79450e081b
commit
ad4418cf9b
@ -81,6 +81,7 @@ public class Bzip2Decoder extends ByteToMessageDecoder {
|
|||||||
if (!in.isReadable()) {
|
if (!in.isReadable()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Bzip2BitReader reader = this.reader;
|
final Bzip2BitReader reader = this.reader;
|
||||||
reader.setByteBuf(in);
|
reader.setByteBuf(in);
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ package io.netty.handler.codec.compression;
|
|||||||
import io.netty.buffer.ByteBuf;
|
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 io.netty.util.internal.EmptyArrays;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.zip.Adler32;
|
import java.util.zip.Adler32;
|
||||||
@ -108,12 +109,11 @@ public class FastLzFrameDecoder extends ByteToMessageDecoder {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
|
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
|
||||||
for (;;) {
|
|
||||||
try {
|
try {
|
||||||
switch (currentState) {
|
switch (currentState) {
|
||||||
case INIT_BLOCK:
|
case INIT_BLOCK:
|
||||||
if (in.readableBytes() < 4) {
|
if (in.readableBytes() < 4) {
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int magic = in.readUnsignedMedium();
|
final int magic = in.readUnsignedMedium();
|
||||||
@ -128,7 +128,7 @@ public class FastLzFrameDecoder extends ByteToMessageDecoder {
|
|||||||
currentState = State.INIT_BLOCK_PARAMS;
|
currentState = State.INIT_BLOCK_PARAMS;
|
||||||
case INIT_BLOCK_PARAMS:
|
case INIT_BLOCK_PARAMS:
|
||||||
if (in.readableBytes() < 2 + (isCompressed ? 2 : 0) + (hasChecksum ? 4 : 0)) {
|
if (in.readableBytes() < 2 + (isCompressed ? 2 : 0) + (hasChecksum ? 4 : 0)) {
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
currentChecksum = hasChecksum ? in.readInt() : 0;
|
currentChecksum = hasChecksum ? in.readInt() : 0;
|
||||||
chunkLength = in.readUnsignedShort();
|
chunkLength = in.readUnsignedShort();
|
||||||
@ -138,15 +138,25 @@ public class FastLzFrameDecoder extends ByteToMessageDecoder {
|
|||||||
case DECOMPRESS_DATA:
|
case DECOMPRESS_DATA:
|
||||||
final int chunkLength = this.chunkLength;
|
final int chunkLength = this.chunkLength;
|
||||||
if (in.readableBytes() < chunkLength) {
|
if (in.readableBytes() < chunkLength) {
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int idx = in.readerIndex();
|
final int idx = in.readerIndex();
|
||||||
final int originalLength = this.originalLength;
|
final int originalLength = this.originalLength;
|
||||||
|
|
||||||
ByteBuf uncompressed = ctx.alloc().heapBuffer(originalLength, originalLength);
|
final ByteBuf uncompressed;
|
||||||
final byte[] output = uncompressed.array();
|
final byte[] output;
|
||||||
final int outputPtr = uncompressed.arrayOffset() + uncompressed.writerIndex();
|
final int outputPtr;
|
||||||
|
|
||||||
|
if (originalLength != 0) {
|
||||||
|
uncompressed = ctx.alloc().heapBuffer(originalLength, originalLength);
|
||||||
|
output = uncompressed.array();
|
||||||
|
outputPtr = uncompressed.arrayOffset() + uncompressed.writerIndex();
|
||||||
|
} else {
|
||||||
|
uncompressed = null;
|
||||||
|
output = EmptyArrays.EMPTY_BYTES;
|
||||||
|
outputPtr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
try {
|
try {
|
||||||
@ -184,8 +194,11 @@ public class FastLzFrameDecoder extends ByteToMessageDecoder {
|
|||||||
checksumResult, currentChecksum));
|
checksumResult, currentChecksum));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (uncompressed != null) {
|
||||||
uncompressed.writerIndex(uncompressed.writerIndex() + originalLength);
|
uncompressed.writerIndex(uncompressed.writerIndex() + originalLength);
|
||||||
out.add(uncompressed);
|
out.add(uncompressed);
|
||||||
|
}
|
||||||
in.skipBytes(chunkLength);
|
in.skipBytes(chunkLength);
|
||||||
|
|
||||||
currentState = State.INIT_BLOCK;
|
currentState = State.INIT_BLOCK;
|
||||||
@ -198,7 +211,7 @@ public class FastLzFrameDecoder extends ByteToMessageDecoder {
|
|||||||
break;
|
break;
|
||||||
case CORRUPTED:
|
case CORRUPTED:
|
||||||
in.skipBytes(in.readableBytes());
|
in.skipBytes(in.readableBytes());
|
||||||
return;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
@ -208,4 +221,3 @@ public class FastLzFrameDecoder extends ByteToMessageDecoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -148,12 +148,11 @@ public class Lz4FrameDecoder extends ByteToMessageDecoder {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
|
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
|
||||||
for (;;) {
|
|
||||||
try {
|
try {
|
||||||
switch (currentState) {
|
switch (currentState) {
|
||||||
case INIT_BLOCK:
|
case INIT_BLOCK:
|
||||||
if (in.readableBytes() < HEADER_LENGTH) {
|
if (in.readableBytes() < HEADER_LENGTH) {
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
final long magic = in.readLong();
|
final long magic = in.readLong();
|
||||||
if (magic != MAGIC_NUMBER) {
|
if (magic != MAGIC_NUMBER) {
|
||||||
@ -210,7 +209,7 @@ public class Lz4FrameDecoder extends ByteToMessageDecoder {
|
|||||||
currentChecksum = this.currentChecksum;
|
currentChecksum = this.currentChecksum;
|
||||||
|
|
||||||
if (in.readableBytes() < compressedLength) {
|
if (in.readableBytes() < compressedLength) {
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int idx = in.readerIndex();
|
final int idx = in.readerIndex();
|
||||||
@ -283,7 +282,7 @@ public class Lz4FrameDecoder extends ByteToMessageDecoder {
|
|||||||
case FINISHED:
|
case FINISHED:
|
||||||
case CORRUPTED:
|
case CORRUPTED:
|
||||||
in.skipBytes(in.readableBytes());
|
in.skipBytes(in.readableBytes());
|
||||||
return;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
@ -292,7 +291,6 @@ public class Lz4FrameDecoder extends ByteToMessageDecoder {
|
|||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns {@code true} if and only if the end of the compressed stream
|
* Returns {@code true} if and only if the end of the compressed stream
|
||||||
|
@ -109,12 +109,11 @@ public class LzfDecoder extends ByteToMessageDecoder {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
|
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
|
||||||
for (;;) {
|
|
||||||
try {
|
try {
|
||||||
switch (currentState) {
|
switch (currentState) {
|
||||||
case INIT_BLOCK:
|
case INIT_BLOCK:
|
||||||
if (in.readableBytes() < HEADER_LEN_NOT_COMPRESSED) {
|
if (in.readableBytes() < HEADER_LEN_NOT_COMPRESSED) {
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
final int magic = in.readUnsignedShort();
|
final int magic = in.readUnsignedShort();
|
||||||
if (magic != MAGIC_NUMBER) {
|
if (magic != MAGIC_NUMBER) {
|
||||||
@ -143,7 +142,7 @@ public class LzfDecoder extends ByteToMessageDecoder {
|
|||||||
}
|
}
|
||||||
case INIT_ORIGINAL_LENGTH:
|
case INIT_ORIGINAL_LENGTH:
|
||||||
if (in.readableBytes() < 2) {
|
if (in.readableBytes() < 2) {
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
originalLength = in.readUnsignedShort();
|
originalLength = in.readUnsignedShort();
|
||||||
|
|
||||||
@ -151,7 +150,7 @@ public class LzfDecoder extends ByteToMessageDecoder {
|
|||||||
case DECOMPRESS_DATA:
|
case DECOMPRESS_DATA:
|
||||||
final int chunkLength = this.chunkLength;
|
final int chunkLength = this.chunkLength;
|
||||||
if (in.readableBytes() < chunkLength) {
|
if (in.readableBytes() < chunkLength) {
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
final int originalLength = this.originalLength;
|
final int originalLength = this.originalLength;
|
||||||
|
|
||||||
@ -189,7 +188,7 @@ public class LzfDecoder extends ByteToMessageDecoder {
|
|||||||
if (!in.hasArray()) {
|
if (!in.hasArray()) {
|
||||||
recycler.releaseInputBuffer(inputArray);
|
recycler.releaseInputBuffer(inputArray);
|
||||||
}
|
}
|
||||||
} else {
|
} else if (chunkLength > 0) {
|
||||||
out.add(in.readSlice(chunkLength).retain());
|
out.add(in.readSlice(chunkLength).retain());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,7 +196,7 @@ public class LzfDecoder extends ByteToMessageDecoder {
|
|||||||
break;
|
break;
|
||||||
case CORRUPTED:
|
case CORRUPTED:
|
||||||
in.skipBytes(in.readableBytes());
|
in.skipBytes(in.readableBytes());
|
||||||
return;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
@ -209,4 +208,3 @@ public class LzfDecoder extends ByteToMessageDecoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user