Skip to content

Commit

Permalink
Merge pull request shyiko#34 from ramanenka/optimize-read-array-in-by…
Browse files Browse the repository at this point in the history
…tearrayinputstream

Optimize read operation on ByteArrayInputStream
  • Loading branch information
osheroff authored Apr 20, 2021
2 parents 252dead + ff9a791 commit 7773a28
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,50 @@ private int readWithinBlockBoundaries() throws IOException {
return inputStream.read();
}

@Override
public int read(byte[] b, int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
} else if (off < 0 || len < 0 || len > b.length - off) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}

if (peek != null) {
b[off] = (byte)(int)peek;
off += 1;
len -= 1;
}

int read = readWithinBlockBoundaries(b, off, len);

if (read > 0) {
this.pos += read;
}

if (peek != null) {
peek = null;
read = read <= 0 ? 1 : read + 1;
}

return read;
}

private int readWithinBlockBoundaries(byte[] b, int off, int len) throws IOException {
if (blockLength == -1) {
return inputStream.read(b, off, len);
} else if (blockLength == 0) {
return -1;
}

int read = inputStream.read(b, off, Math.min(len, blockLength));
if (read > 0) {
blockLength -= read;
}
return read;
}

@Override
public void close() throws IOException {
inputStream.close();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package com.github.shyiko.mysql.binlog.io;

import org.testng.annotations.Test;

import static org.testng.Assert.assertEquals;

public class ByteArrayInputStreamTest {
@Test
public void testReadToArray() throws Exception {
byte[] buff = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
ByteArrayInputStream in = new ByteArrayInputStream(buff);
assertEquals(in.getPosition(), 0);

byte[] b = new byte[20];

int read = in.read(b, 0, 0);
assertEquals(read, 0);
assertEquals(in.getPosition(), 0);

read = in.read(b, 0, 4);
assertEquals(read, 4);
assertEquals(b[3], 3);
assertEquals(in.getPosition(), 4);

read = in.read(b, 4, 4);
assertEquals(read, 4);
assertEquals(b[7], 7);
assertEquals(in.getPosition(), 8);

read = in.read(b, 8, 4);
assertEquals(read, 4);
assertEquals(b[11], 11);
assertEquals(in.getPosition(), 12);

read = in.read(b, 12, 4);
assertEquals(read, 4);
assertEquals(b[15], 15);
assertEquals(in.getPosition(), 16);

read = in.read(b, 16, 4);
assertEquals(read, -1);
assertEquals(in.getPosition(), 16);
}

@Test
public void testReadToArrayWithinBlockBoundaries() throws Exception {
byte[] buff = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8};
ByteArrayInputStream in = new ByteArrayInputStream(buff);
byte[] b = new byte[8];

in.enterBlock(4);

int read = in.read(b, 0, 3);
assertEquals(read, 3);
assertEquals(b[2], 2);

read = in.read(b, 3, 3);
assertEquals(read, 1);
assertEquals(b[3], 3);

read = in.read(b, 4, 3);
assertEquals(read, -1);
}

@Test(expectedExceptions = NullPointerException.class)
public void testReadToArrayWithNullBuff() throws Exception {
ByteArrayInputStream in = new ByteArrayInputStream(new byte[]{});
in.read(null, 0, 4);
}

@Test(expectedExceptions = IndexOutOfBoundsException.class)
public void testReadToArrayWhenLenExceedsBuffSize() throws Exception {
ByteArrayInputStream in = new ByteArrayInputStream(new byte[]{0, 1, 2});
byte[] b = new byte[1];
in.read(b, 0, 4);
}

@Test(expectedExceptions = IndexOutOfBoundsException.class)
public void testReadToArrayWhenOffsetNegative() throws Exception {
ByteArrayInputStream in = new ByteArrayInputStream(new byte[]{0, 1, 2});
byte[] b = new byte[1];
in.read(b, -1, 1);
}

@Test(expectedExceptions = IndexOutOfBoundsException.class)
public void testReadToArrayWhenLengthNegative() throws Exception {
ByteArrayInputStream in = new ByteArrayInputStream(new byte[]{0, 1, 2});
byte[] b = new byte[1];
in.read(b, 0, -1);
}

@Test
public void testPeekAndReadToArray() throws Exception {
ByteArrayInputStream in = new ByteArrayInputStream(new byte[]{5, 6, 7});
byte[] b = new byte[3];
assertEquals(in.peek(), 5);
int read = in.read(b, 0, 3);
assertEquals(read, 3);
assertEquals(b[0], 5);
assertEquals(b[2], 7);
}
}

0 comments on commit 7773a28

Please sign in to comment.