diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/io/ByteBufferWriterOutputStream.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/io/ByteBufferWriterOutputStream.java index 6d46fa8..118d352 100644 --- a/hbase-common/src/main/java/org/apache/hadoop/hbase/io/ByteBufferWriterOutputStream.java +++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/io/ByteBufferWriterOutputStream.java @@ -22,8 +22,6 @@ import java.io.OutputStream; import java.nio.ByteBuffer; import org.apache.hadoop.hbase.io.util.StreamUtils; -import org.apache.hadoop.hbase.util.ByteBufferUtils; -import org.apache.yetus.audience.InterfaceAudience; /** * When deal with OutputStream which is not ByteBufferWriter type, wrap it with this class. We will @@ -37,34 +35,53 @@ import org.apache.yetus.audience.InterfaceAudience; *
* Note: This class is not thread safe. */ -@InterfaceAudience.Private -public class ByteBufferWriterOutputStream extends OutputStream - implements ByteBufferWriter { +public class ByteBufferWriterOutputStream extends OutputStream { + + private static int DEFAULT_BUFFER_SIZE = 8192; - private static final int TEMP_BUF_LENGTH = 4 * 1024; private final OutputStream os; - private byte[] tempBuf = null; + private final byte[] buf; + private final int bufSize; public ByteBufferWriterOutputStream(OutputStream os) { + this(os, DEFAULT_BUFFER_SIZE); + } + + public ByteBufferWriterOutputStream(OutputStream os, int size) { this.os = os; + this.buf = new byte[size]; + this.bufSize = size; } - @Override + /** + * Writes len bytes from the specified ByteBuffer starting at offset off to + * this OutputStream. If b is null, a NullPointerException is thrown. If off + * is negative or larger than the ByteBuffer then an IllegalArgumentException + * is thrown. If len is greater than the length of the ByteBuffer, then an + * BufferUnderflowException is thrown. This method does not change the + * position of the ByteBuffer. + * + * @param b + * the ByteBuffer + * @param off + * the start offset in the data + * @param len + * the number of bytes to write + * @throws IOException + * if an I/O error occurs. In particular, an IOException is thrown + * if the output stream is closed. + */ public void write(ByteBuffer b, int off, int len) throws IOException { - byte[] buf = null; - if (len > TEMP_BUF_LENGTH) { - buf = new byte[len]; - } else { - if (this.tempBuf == null) { - this.tempBuf = new byte[TEMP_BUF_LENGTH]; - } - buf = this.tempBuf; + ByteBuffer c = (ByteBuffer) b.duplicate().position(off); + int totalCopied = 0; + while (totalCopied < len) { + int bytesToCopy = Math.min((len - totalCopied), bufSize); + c.get(buf, 0, bytesToCopy); + os.write(buf, 0, bytesToCopy); + totalCopied += bytesToCopy; } - ByteBufferUtils.copyFromBufferToArray(buf, b, off, 0, len); - this.os.write(buf, 0, len); } - @Override public void writeInt(int i) throws IOException { StreamUtils.writeInt(this.os, i); } @@ -75,7 +92,7 @@ public class ByteBufferWriterOutputStream extends OutputStream } @Override - public void write(byte b[], int off, int len) throws IOException { + public void write(byte[] b, int off, int len) throws IOException { this.os.write(b, off, len); } diff --git a/hbase-common/src/test/java/org/apache/hadoop/hbase/io/TestByteBufferWriterOutputStream.java b/hbase-common/src/test/java/org/apache/hadoop/hbase/io/TestByteBufferWriterOutputStream.java index 7e782de..47d285e 100644 --- a/hbase-common/src/test/java/org/apache/hadoop/hbase/io/TestByteBufferWriterOutputStream.java +++ b/hbase-common/src/test/java/org/apache/hadoop/hbase/io/TestByteBufferWriterOutputStream.java @@ -17,7 +17,7 @@ import org.junit.experimental.categories.Category; @Category({ IOTests.class, SmallTests.class }) public class TestByteBufferWriterOutputStream { - private static final Random RANDOM = new Random(31l); + private static final Random RANDOM = new Random(31L); // Default buffer size is 8Kb = pick number that does not fall on a boundary private static final int TEST_BUF_SIZE = 16512;