Skip to content

Commit 7773a28

Browse files
authored
Merge pull request osheroff#34 from ramanenka/optimize-read-array-in-bytearrayinputstream
Optimize read operation on ByteArrayInputStream
2 parents 252dead + ff9a791 commit 7773a28

File tree

2 files changed

+146
-0
lines changed

2 files changed

+146
-0
lines changed

src/main/java/com/github/shyiko/mysql/binlog/io/ByteArrayInputStream.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,50 @@ private int readWithinBlockBoundaries() throws IOException {
222222
return inputStream.read();
223223
}
224224

225+
@Override
226+
public int read(byte[] b, int off, int len) throws IOException {
227+
if (b == null) {
228+
throw new NullPointerException();
229+
} else if (off < 0 || len < 0 || len > b.length - off) {
230+
throw new IndexOutOfBoundsException();
231+
} else if (len == 0) {
232+
return 0;
233+
}
234+
235+
if (peek != null) {
236+
b[off] = (byte)(int)peek;
237+
off += 1;
238+
len -= 1;
239+
}
240+
241+
int read = readWithinBlockBoundaries(b, off, len);
242+
243+
if (read > 0) {
244+
this.pos += read;
245+
}
246+
247+
if (peek != null) {
248+
peek = null;
249+
read = read <= 0 ? 1 : read + 1;
250+
}
251+
252+
return read;
253+
}
254+
255+
private int readWithinBlockBoundaries(byte[] b, int off, int len) throws IOException {
256+
if (blockLength == -1) {
257+
return inputStream.read(b, off, len);
258+
} else if (blockLength == 0) {
259+
return -1;
260+
}
261+
262+
int read = inputStream.read(b, off, Math.min(len, blockLength));
263+
if (read > 0) {
264+
blockLength -= read;
265+
}
266+
return read;
267+
}
268+
225269
@Override
226270
public void close() throws IOException {
227271
inputStream.close();
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package com.github.shyiko.mysql.binlog.io;
2+
3+
import org.testng.annotations.Test;
4+
5+
import static org.testng.Assert.assertEquals;
6+
7+
public class ByteArrayInputStreamTest {
8+
@Test
9+
public void testReadToArray() throws Exception {
10+
byte[] buff = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
11+
ByteArrayInputStream in = new ByteArrayInputStream(buff);
12+
assertEquals(in.getPosition(), 0);
13+
14+
byte[] b = new byte[20];
15+
16+
int read = in.read(b, 0, 0);
17+
assertEquals(read, 0);
18+
assertEquals(in.getPosition(), 0);
19+
20+
read = in.read(b, 0, 4);
21+
assertEquals(read, 4);
22+
assertEquals(b[3], 3);
23+
assertEquals(in.getPosition(), 4);
24+
25+
read = in.read(b, 4, 4);
26+
assertEquals(read, 4);
27+
assertEquals(b[7], 7);
28+
assertEquals(in.getPosition(), 8);
29+
30+
read = in.read(b, 8, 4);
31+
assertEquals(read, 4);
32+
assertEquals(b[11], 11);
33+
assertEquals(in.getPosition(), 12);
34+
35+
read = in.read(b, 12, 4);
36+
assertEquals(read, 4);
37+
assertEquals(b[15], 15);
38+
assertEquals(in.getPosition(), 16);
39+
40+
read = in.read(b, 16, 4);
41+
assertEquals(read, -1);
42+
assertEquals(in.getPosition(), 16);
43+
}
44+
45+
@Test
46+
public void testReadToArrayWithinBlockBoundaries() throws Exception {
47+
byte[] buff = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8};
48+
ByteArrayInputStream in = new ByteArrayInputStream(buff);
49+
byte[] b = new byte[8];
50+
51+
in.enterBlock(4);
52+
53+
int read = in.read(b, 0, 3);
54+
assertEquals(read, 3);
55+
assertEquals(b[2], 2);
56+
57+
read = in.read(b, 3, 3);
58+
assertEquals(read, 1);
59+
assertEquals(b[3], 3);
60+
61+
read = in.read(b, 4, 3);
62+
assertEquals(read, -1);
63+
}
64+
65+
@Test(expectedExceptions = NullPointerException.class)
66+
public void testReadToArrayWithNullBuff() throws Exception {
67+
ByteArrayInputStream in = new ByteArrayInputStream(new byte[]{});
68+
in.read(null, 0, 4);
69+
}
70+
71+
@Test(expectedExceptions = IndexOutOfBoundsException.class)
72+
public void testReadToArrayWhenLenExceedsBuffSize() throws Exception {
73+
ByteArrayInputStream in = new ByteArrayInputStream(new byte[]{0, 1, 2});
74+
byte[] b = new byte[1];
75+
in.read(b, 0, 4);
76+
}
77+
78+
@Test(expectedExceptions = IndexOutOfBoundsException.class)
79+
public void testReadToArrayWhenOffsetNegative() throws Exception {
80+
ByteArrayInputStream in = new ByteArrayInputStream(new byte[]{0, 1, 2});
81+
byte[] b = new byte[1];
82+
in.read(b, -1, 1);
83+
}
84+
85+
@Test(expectedExceptions = IndexOutOfBoundsException.class)
86+
public void testReadToArrayWhenLengthNegative() throws Exception {
87+
ByteArrayInputStream in = new ByteArrayInputStream(new byte[]{0, 1, 2});
88+
byte[] b = new byte[1];
89+
in.read(b, 0, -1);
90+
}
91+
92+
@Test
93+
public void testPeekAndReadToArray() throws Exception {
94+
ByteArrayInputStream in = new ByteArrayInputStream(new byte[]{5, 6, 7});
95+
byte[] b = new byte[3];
96+
assertEquals(in.peek(), 5);
97+
int read = in.read(b, 0, 3);
98+
assertEquals(read, 3);
99+
assertEquals(b[0], 5);
100+
assertEquals(b[2], 7);
101+
}
102+
}

0 commit comments

Comments
 (0)