Skip to content

Commit

Permalink
Add TestZlib using JDK implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
electrum committed Mar 31, 2023
1 parent edaa2d0 commit 6cd87ba
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@

import io.airlift.compress.Compressor;

import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.util.zip.Deflater;

import static com.google.common.base.Preconditions.checkPositionIndexes;
import static java.util.zip.Deflater.FULL_FLUSH;

public class JdkDeflateCompressor
Expand All @@ -26,23 +28,75 @@ public class JdkDeflateCompressor
@Override
public int maxCompressedLength(int uncompressedSize)
{
return (int) ((uncompressedSize * 1.2) + 11);
// From Mark Adler's post http://stackoverflow.com/questions/1207877/java-size-of-compression-output-bytearray
return uncompressedSize + ((uncompressedSize + 7) >> 3) + ((uncompressedSize + 63) >> 6) + 5;
}

@Override
public int compress(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, int maxOutputLength)
{
checkPositionIndexes(inputOffset, inputOffset + inputLength, input.length);
checkPositionIndexes(outputOffset, outputOffset + maxOutputLength, output.length);

if (maxOutputLength < maxCompressedLength(inputLength)) {
throw new IllegalArgumentException("Max output length must be larger than " + maxCompressedLength(inputLength));
}

Deflater deflater = new Deflater(6, true);
deflater.setInput(input, inputOffset, inputLength);
deflater.finish();
int compressedDataLength = deflater.deflate(output, outputOffset, maxOutputLength, FULL_FLUSH);
deflater.end();
return compressedDataLength;
try {
deflater.setInput(input, inputOffset, inputLength);
deflater.finish();
int size = deflater.deflate(output, outputOffset, maxOutputLength, FULL_FLUSH);
if (!deflater.finished()) {
throw new RuntimeException("maxCompressedLength formula is incorrect, because deflate produced more data");
}
return size;
}
finally {
deflater.end();
}
}

@SuppressWarnings("RedundantCast") // allow running on JDK 8
@Override
public void compress(ByteBuffer input, ByteBuffer output)
{
throw new UnsupportedOperationException("not yet implemented");
byte[] inputArray;
int inputOffset;
int inputLength;
if (input.hasArray()) {
inputArray = input.array();
inputOffset = input.arrayOffset() + input.position();
inputLength = input.remaining();
}
else {
inputArray = new byte[input.remaining()];
inputOffset = 0;
inputLength = inputArray.length;
input.get(inputArray);
}

byte[] outputArray;
int outputOffset;
int outputLength;
if (output.hasArray()) {
outputArray = output.array();
outputOffset = output.arrayOffset() + output.position();
outputLength = output.remaining();
}
else {
outputArray = new byte[output.remaining()];
outputOffset = 0;
outputLength = outputArray.length;
}

int written = compress(inputArray, inputOffset, inputLength, outputArray, outputOffset, outputLength);

if (output.hasArray()) {
((Buffer) output).position(output.position() + written);
}
else {
output.put(outputArray, outputOffset, written);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,33 +16,81 @@
import io.airlift.compress.Decompressor;
import io.airlift.compress.MalformedInputException;

import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.util.zip.DataFormatException;
import java.util.zip.Inflater;

import static com.google.common.base.Preconditions.checkPositionIndexes;

public class JdkInflateDecompressor
implements Decompressor
{
@Override
public int decompress(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, int maxOutputLength)
throws MalformedInputException
{
checkPositionIndexes(inputOffset, inputOffset + inputLength, input.length);
checkPositionIndexes(outputOffset, outputOffset + maxOutputLength, output.length);

Inflater inflater = new Inflater(true);
try {
Inflater inflater = new Inflater(true);
inflater.setInput(input, inputOffset, inputLength);
int resultLength = inflater.inflate(output, outputOffset, maxOutputLength);
inflater.end();
if (!inflater.finished()) {
throw new MalformedInputException(inflater.getBytesRead());
}
return resultLength;
}
catch (DataFormatException e) {
throw new RuntimeException(e);
}
finally {
inflater.end();
}
}

@SuppressWarnings("RedundantCast") // allow running on JDK 8
@Override
public void decompress(ByteBuffer input, ByteBuffer output)
throws MalformedInputException
{
throw new UnsupportedOperationException("not yet implemented");
byte[] inputArray;
int inputOffset;
int inputLength;
if (input.hasArray()) {
inputArray = input.array();
inputOffset = input.arrayOffset() + input.position();
inputLength = input.remaining();
}
else {
inputArray = new byte[input.remaining()];
inputOffset = 0;
inputLength = inputArray.length;
input.get(inputArray);
}

byte[] outputArray;
int outputOffset;
int outputLength;
if (output.hasArray()) {
outputArray = output.array();
outputOffset = output.arrayOffset() + output.position();
outputLength = output.remaining();
}
else {
outputArray = new byte[output.remaining()];
outputOffset = 0;
outputLength = outputArray.length;
}

int written = decompress(inputArray, inputOffset, inputLength, outputArray, outputOffset, outputLength);

if (output.hasArray()) {
((Buffer) output).position(output.position() + written);
}
else {
output.put(outputArray, outputOffset, written);
}
}
}
48 changes: 48 additions & 0 deletions src/test/java/io/airlift/compress/zlib/TestZlib.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.airlift.compress.zlib;

import io.airlift.compress.AbstractTestCompression;
import io.airlift.compress.Compressor;
import io.airlift.compress.Decompressor;
import io.airlift.compress.thirdparty.JdkDeflateCompressor;
import io.airlift.compress.thirdparty.JdkInflateDecompressor;

public class TestZlib
extends AbstractTestCompression
{
@Override
protected Compressor getCompressor()
{
return new JdkDeflateCompressor();
}

@Override
protected Decompressor getDecompressor()
{
return new JdkInflateDecompressor();
}

@Override
protected Compressor getVerifyCompressor()
{
return new JdkDeflateCompressor();
}

@Override
protected Decompressor getVerifyDecompressor()
{
return new JdkInflateDecompressor();
}
}

0 comments on commit 6cd87ba

Please sign in to comment.