kryo compression now uses optimized int instead of standard int
This commit is contained in:
parent
d91ee89102
commit
37224b3097
@ -18,7 +18,7 @@ package dorkbox.network.connection;
|
|||||||
import com.esotericsoftware.kryo.Kryo;
|
import com.esotericsoftware.kryo.Kryo;
|
||||||
import dorkbox.network.pipeline.ByteBufInput;
|
import dorkbox.network.pipeline.ByteBufInput;
|
||||||
import dorkbox.network.pipeline.ByteBufOutput;
|
import dorkbox.network.pipeline.ByteBufOutput;
|
||||||
import dorkbox.util.bytes.BigEndian;
|
import dorkbox.util.bytes.OptimizeUtilsByteArray;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import net.jpountz.lz4.LZ4Compressor;
|
import net.jpountz.lz4.LZ4Compressor;
|
||||||
@ -122,6 +122,12 @@ class KryoExtra extends Kryo {
|
|||||||
|
|
||||||
public synchronized
|
public synchronized
|
||||||
void writeCrypto(final ConnectionImpl connection, final ByteBuf buffer, final Object message, final Logger logger) throws IOException {
|
void writeCrypto(final ConnectionImpl connection, final ByteBuf buffer, final Object message, final Logger logger) throws IOException {
|
||||||
|
// connection will ALWAYS be of type Connection
|
||||||
|
// used by RMI/some serializers to determine which connection wrote this object
|
||||||
|
// NOTE: this is only valid in the context of this thread, which RMI stuff is accessed in -- so this is SAFE for RMI
|
||||||
|
this.connection = connection;
|
||||||
|
|
||||||
|
|
||||||
final boolean traceEnabled = logger.isTraceEnabled();
|
final boolean traceEnabled = logger.isTraceEnabled();
|
||||||
|
|
||||||
ByteBuf objectOutputBuffer = this.tempBuffer;
|
ByteBuf objectOutputBuffer = this.tempBuffer;
|
||||||
@ -176,10 +182,11 @@ class KryoExtra extends Kryo {
|
|||||||
|
|
||||||
byte[] compressOutput = this.compressOutput;
|
byte[] compressOutput = this.compressOutput;
|
||||||
|
|
||||||
|
int maxLengthLengthOffset = 5;
|
||||||
int maxCompressedLength = compressor.maxCompressedLength(length);
|
int maxCompressedLength = compressor.maxCompressedLength(length);
|
||||||
|
|
||||||
// add 4 so there is room to write the compressed size to the buffer
|
// add 5 so there is room to write the compressed size to the buffer
|
||||||
int maxCompressedLengthWithOffset = maxCompressedLength + 4;
|
int maxCompressedLengthWithOffset = maxCompressedLength + maxLengthLengthOffset;
|
||||||
|
|
||||||
// lazy initialize the compression output buffer
|
// lazy initialize the compression output buffer
|
||||||
if (maxCompressedLengthWithOffset > compressOutputLength) {
|
if (maxCompressedLengthWithOffset > compressOutputLength) {
|
||||||
@ -189,20 +196,24 @@ class KryoExtra extends Kryo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// LZ4 compress. output offset 4 to leave room for length of tempOutput data
|
|
||||||
int compressedLength = compressor.compress(inputArray, inputOffset, length, compressOutput, 4, maxCompressedLength);
|
// LZ4 compress. output offset max 5 bytes to leave room for length of tempOutput data
|
||||||
|
int compressedLength = compressor.compress(inputArray, inputOffset, length, compressOutput, maxLengthLengthOffset, maxCompressedLength);
|
||||||
|
|
||||||
// bytes can now be written to, because our compressed data is stored in a temp array.
|
// bytes can now be written to, because our compressed data is stored in a temp array.
|
||||||
|
|
||||||
// now write the ORIGINAL (uncompressed) length to the front of the byte array. This is so we can use the FAST decompress version
|
final int lengthLength = OptimizeUtilsByteArray.intLength(length, true);
|
||||||
BigEndian.Int_.toBytes(length, compressOutput);
|
|
||||||
|
|
||||||
// corrected length
|
|
||||||
length = compressedLength + 4; // +4 for the uncompressed size bytes
|
|
||||||
|
|
||||||
// correct input. compression output is now encryption input
|
// correct input. compression output is now encryption input
|
||||||
inputArray = compressOutput;
|
inputArray = compressOutput;
|
||||||
inputOffset = 0;
|
inputOffset = maxLengthLengthOffset - lengthLength;
|
||||||
|
|
||||||
|
|
||||||
|
// now write the ORIGINAL (uncompressed) length to the front of the byte array. This is so we can use the FAST decompress version
|
||||||
|
OptimizeUtilsByteArray.writeInt(inputArray, length, true, inputOffset);
|
||||||
|
|
||||||
|
// correct length for encryption
|
||||||
|
length = compressedLength + lengthLength; // +1 to +5 for the uncompressed size bytes
|
||||||
|
|
||||||
if (traceEnabled) {
|
if (traceEnabled) {
|
||||||
logger.trace("AES encrypting data {}", connection);
|
logger.trace("AES encrypting data {}", connection);
|
||||||
@ -247,7 +258,7 @@ class KryoExtra extends Kryo {
|
|||||||
|
|
||||||
public
|
public
|
||||||
Object readCrypto(final ConnectionImpl connection, final ByteBuf buffer, int length, final Logger logger) throws IOException {
|
Object readCrypto(final ConnectionImpl connection, final ByteBuf buffer, int length, final Logger logger) throws IOException {
|
||||||
// connection will ALWAYS be of type IConnection or NULL.
|
// connection will ALWAYS be of type IConnection
|
||||||
// used by RMI/some serializers to determine which connection read this object
|
// used by RMI/some serializers to determine which connection read this object
|
||||||
// NOTE: this is only valid in the context of this thread, which RMI stuff is accessed in -- so this is SAFE for RMI
|
// NOTE: this is only valid in the context of this thread, which RMI stuff is accessed in -- so this is SAFE for RMI
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
@ -279,6 +290,7 @@ class KryoExtra extends Kryo {
|
|||||||
byte[] inputArray;
|
byte[] inputArray;
|
||||||
int inputOffset;
|
int inputOffset;
|
||||||
|
|
||||||
|
//noinspection Duplicates
|
||||||
if (inputBuf.hasArray()) {
|
if (inputBuf.hasArray()) {
|
||||||
// Even if a ByteBuf has a backing array (i.e. buf.hasArray() returns true), the following isn't necessarily true because
|
// Even if a ByteBuf has a backing array (i.e. buf.hasArray() returns true), the following isn't necessarily true because
|
||||||
// the buffer might be a slice of other buffer or a pooled buffer:
|
// the buffer might be a slice of other buffer or a pooled buffer:
|
||||||
@ -332,11 +344,12 @@ class KryoExtra extends Kryo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// decompress -- as it's ALWAYS compressed
|
// decompress -- as it's ALWAYS compressed
|
||||||
inputArray = decryptOutputArray;
|
|
||||||
inputOffset = 4; // because 4 bytes for the decompressed size
|
|
||||||
|
|
||||||
// get the decompressed length (at the beginning of the array)
|
// get the decompressed length (at the beginning of the array)
|
||||||
final int uncompressedLength = BigEndian.Int_.from(inputArray);
|
inputArray = decryptOutputArray;
|
||||||
|
final int uncompressedLength = OptimizeUtilsByteArray.readInt(inputArray, true);
|
||||||
|
inputOffset = OptimizeUtilsByteArray.intLength(uncompressedLength, true); // because 1-5 bytes for the decompressed size
|
||||||
|
|
||||||
|
|
||||||
byte[] decompressOutputArray = this.decompressOutput;
|
byte[] decompressOutputArray = this.decompressOutput;
|
||||||
if (uncompressedLength > decompressOutputLength) {
|
if (uncompressedLength > decompressOutputLength) {
|
||||||
@ -346,18 +359,17 @@ class KryoExtra extends Kryo {
|
|||||||
|
|
||||||
decompressBuf = Unpooled.wrappedBuffer(decompressOutputArray); // so we can read via kryo
|
decompressBuf = Unpooled.wrappedBuffer(decompressOutputArray); // so we can read via kryo
|
||||||
}
|
}
|
||||||
|
inputBuf = decompressBuf;
|
||||||
|
|
||||||
// LZ4 decompress, requires the size of the ORIGINAL length (because we use the FAST decompressor
|
// LZ4 decompress, requires the size of the ORIGINAL length (because we use the FAST decompressor
|
||||||
decompressor.decompress(inputArray, inputOffset, decompressOutputArray, 0, uncompressedLength);
|
decompressor.decompress(inputArray, inputOffset, decompressOutputArray, 0, uncompressedLength);
|
||||||
|
|
||||||
decompressBuf.setIndex(0, uncompressedLength);
|
inputBuf.setIndex(0, uncompressedLength);
|
||||||
inputBuf = decompressBuf;
|
|
||||||
|
|
||||||
// read the object from the buffer.
|
// read the object from the buffer.
|
||||||
reader.setBuffer(inputBuf);
|
reader.setBuffer(inputBuf);
|
||||||
|
|
||||||
return readClassAndObject(reader); // this properly sets the readerIndex, but only if it's the correct buffer
|
return readClassAndObject(reader); // this properly sets the readerIndex, but only if it's the correct buffer
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
Reference in New Issue
Block a user