|
@@ -22,22 +22,36 @@ import java.io.EOFException;
|
|
import java.io.IOException;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.InputStream;
|
|
|
|
|
|
|
|
+import com.google.common.annotations.VisibleForTesting;
|
|
import org.apache.hadoop.classification.InterfaceAudience;
|
|
import org.apache.hadoop.classification.InterfaceAudience;
|
|
import org.apache.hadoop.classification.InterfaceStability;
|
|
import org.apache.hadoop.classification.InterfaceStability;
|
|
-import org.apache.hadoop.io.compress.Decompressor;
|
|
|
|
|
|
|
|
@InterfaceAudience.Public
|
|
@InterfaceAudience.Public
|
|
@InterfaceStability.Evolving
|
|
@InterfaceStability.Evolving
|
|
public class DecompressorStream extends CompressionInputStream {
|
|
public class DecompressorStream extends CompressionInputStream {
|
|
|
|
+ /**
|
|
|
|
+ * The maximum input buffer size.
|
|
|
|
+ */
|
|
|
|
+ private static final int MAX_INPUT_BUFFER_SIZE = 512;
|
|
|
|
+ /**
|
|
|
|
+ * MAX_SKIP_BUFFER_SIZE is used to determine the maximum buffer size to
|
|
|
|
+ * use when skipping. See {@link java.io.InputStream}.
|
|
|
|
+ */
|
|
|
|
+ private static final int MAX_SKIP_BUFFER_SIZE = 2048;
|
|
|
|
+
|
|
|
|
+ private byte[] skipBytes;
|
|
|
|
+ private byte[] oneByte = new byte[1];
|
|
|
|
+
|
|
protected Decompressor decompressor = null;
|
|
protected Decompressor decompressor = null;
|
|
protected byte[] buffer;
|
|
protected byte[] buffer;
|
|
protected boolean eof = false;
|
|
protected boolean eof = false;
|
|
protected boolean closed = false;
|
|
protected boolean closed = false;
|
|
private int lastBytesSent = 0;
|
|
private int lastBytesSent = 0;
|
|
|
|
|
|
- public DecompressorStream(InputStream in, Decompressor decompressor,
|
|
|
|
- int bufferSize)
|
|
|
|
- throws IOException {
|
|
|
|
|
|
+ @VisibleForTesting
|
|
|
|
+ DecompressorStream(InputStream in, Decompressor decompressor,
|
|
|
|
+ int bufferSize, int skipBufferSize)
|
|
|
|
+ throws IOException {
|
|
super(in);
|
|
super(in);
|
|
|
|
|
|
if (decompressor == null) {
|
|
if (decompressor == null) {
|
|
@@ -48,11 +62,18 @@ public class DecompressorStream extends CompressionInputStream {
|
|
|
|
|
|
this.decompressor = decompressor;
|
|
this.decompressor = decompressor;
|
|
buffer = new byte[bufferSize];
|
|
buffer = new byte[bufferSize];
|
|
|
|
+ skipBytes = new byte[skipBufferSize];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public DecompressorStream(InputStream in, Decompressor decompressor,
|
|
|
|
+ int bufferSize)
|
|
|
|
+ throws IOException {
|
|
|
|
+ this(in, decompressor, bufferSize, MAX_SKIP_BUFFER_SIZE);
|
|
}
|
|
}
|
|
|
|
|
|
public DecompressorStream(InputStream in, Decompressor decompressor)
|
|
public DecompressorStream(InputStream in, Decompressor decompressor)
|
|
- throws IOException {
|
|
|
|
- this(in, decompressor, 512);
|
|
|
|
|
|
+ throws IOException {
|
|
|
|
+ this(in, decompressor, MAX_INPUT_BUFFER_SIZE);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -64,8 +85,7 @@ public class DecompressorStream extends CompressionInputStream {
|
|
protected DecompressorStream(InputStream in) throws IOException {
|
|
protected DecompressorStream(InputStream in) throws IOException {
|
|
super(in);
|
|
super(in);
|
|
}
|
|
}
|
|
-
|
|
|
|
- private byte[] oneByte = new byte[1];
|
|
|
|
|
|
+
|
|
@Override
|
|
@Override
|
|
public int read() throws IOException {
|
|
public int read() throws IOException {
|
|
checkStream();
|
|
checkStream();
|
|
@@ -86,7 +106,7 @@ public class DecompressorStream extends CompressionInputStream {
|
|
}
|
|
}
|
|
|
|
|
|
protected int decompress(byte[] b, int off, int len) throws IOException {
|
|
protected int decompress(byte[] b, int off, int len) throws IOException {
|
|
- int n = 0;
|
|
|
|
|
|
+ int n;
|
|
|
|
|
|
while ((n = decompressor.decompress(b, off, len)) == 0) {
|
|
while ((n = decompressor.decompress(b, off, len)) == 0) {
|
|
if (decompressor.needsDictionary()) {
|
|
if (decompressor.needsDictionary()) {
|
|
@@ -170,7 +190,6 @@ public class DecompressorStream extends CompressionInputStream {
|
|
decompressor.reset();
|
|
decompressor.reset();
|
|
}
|
|
}
|
|
|
|
|
|
- private byte[] skipBytes = new byte[512];
|
|
|
|
@Override
|
|
@Override
|
|
public long skip(long n) throws IOException {
|
|
public long skip(long n) throws IOException {
|
|
// Sanity checks
|
|
// Sanity checks
|
|
@@ -178,7 +197,7 @@ public class DecompressorStream extends CompressionInputStream {
|
|
throw new IllegalArgumentException("negative skip length");
|
|
throw new IllegalArgumentException("negative skip length");
|
|
}
|
|
}
|
|
checkStream();
|
|
checkStream();
|
|
-
|
|
|
|
|
|
+
|
|
// Read 'n' bytes
|
|
// Read 'n' bytes
|
|
int skipped = 0;
|
|
int skipped = 0;
|
|
while (skipped < n) {
|
|
while (skipped < n) {
|