Skip to content

Commit 3fa6196

Browse files
author
diego Dupin
committed
[misc] performance improvement for multi-rows result-set.
1 parent 960c82d commit 3fa6196

File tree

7 files changed

+92
-100
lines changed

7 files changed

+92
-100
lines changed

src/main/java/org/mariadb/jdbc/client/ReadableByteBuf.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,10 @@ public interface ReadableByteBuf {
1515

1616
byte[] buf();
1717

18-
ReadableByteBuf buf(byte[] buf, int limit);
18+
void buf(byte[] buf, int limit, int pos);
1919

2020
void pos(int pos);
2121

22-
void mark();
23-
24-
void reset();
25-
2622
void skip();
2723

2824
ReadableByteBuf skip(int length);
@@ -65,7 +61,7 @@ public interface ReadableByteBuf {
6561

6662
long readLongBE();
6763

68-
ReadableByteBuf readBytes(byte[] dst);
64+
void readBytes(byte[] dst);
6965

7066
byte[] readBytesNullEnd();
7167

src/main/java/org/mariadb/jdbc/client/impl/StandardReadableByteBuf.java

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,12 @@ public final class StandardReadableByteBuf implements ReadableByteBuf {
1414
private int limit;
1515
private byte[] buf;
1616
private int pos;
17-
private int mark;
1817

1918
public StandardReadableByteBuf(MutableInt sequence, byte[] buf, int limit) {
2019
this.sequence = sequence;
2120
this.pos = 0;
2221
this.buf = buf;
2322
this.limit = limit;
24-
this.mark = -1;
2523
}
2624

2725
public int readableBytes() {
@@ -36,25 +34,16 @@ public byte[] buf() {
3634
return buf;
3735
}
3836

39-
public StandardReadableByteBuf buf(byte[] buf, int limit) {
37+
public void buf(byte[] buf, int limit, int pos) {
4038
this.buf = buf;
4139
this.limit = limit;
42-
return this;
40+
this.pos = pos;
4341
}
4442

4543
public void pos(int pos) {
4644
this.pos = pos;
4745
}
4846

49-
public void mark() {
50-
mark = pos;
51-
}
52-
53-
public void reset() {
54-
if (mark == -1) throw new IllegalStateException("mark was not set");
55-
pos = mark;
56-
}
57-
5847
public void skip() {
5948
pos++;
6049
}
@@ -202,10 +191,9 @@ public long readLongBE() {
202191
+ (buf[pos++] & 0xffL));
203192
}
204193

205-
public StandardReadableByteBuf readBytes(byte[] dst) {
194+
public void readBytes(byte[] dst) {
206195
System.arraycopy(buf, pos, dst, 0, dst.length);
207196
pos += dst.length;
208-
return this;
209197
}
210198

211199
public byte[] readBytesNullEnd() {

src/main/java/org/mariadb/jdbc/client/socket/impl/CompressOutputStream.java

Lines changed: 39 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -78,51 +78,50 @@ public void write(byte[] b, int off, int len) throws IOException {
7878
out.write(b, off, len);
7979

8080
} else {
81-
// *******************************************************************************
82-
// compressing packet
83-
// *******************************************************************************
84-
int sent = 0;
85-
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
86-
try (DeflaterOutputStream deflater = new DeflaterOutputStream(baos)) {
87-
88-
/**
89-
* For multi packet, len will be 0x00ffffff + 4 bytes for header.
90-
* but compression can only compress up to 0x00ffffff bytes (header initial length size cannot be > 3 bytes)
91-
* so, for this specific case, a buffer will be
92-
*/
93-
94-
if (longPacketBuffer != null) {
95-
deflater.write(longPacketBuffer, 0, longPacketBuffer.length);
96-
sent = longPacketBuffer.length;
97-
longPacketBuffer = null;
98-
}
99-
if ( len + sent > 0x00ffffff) {
100-
int remaining = len + sent - 0x00ffffff;
101-
longPacketBuffer = new byte[remaining];
102-
System.arraycopy(b, off + 0x00ffffff - sent, longPacketBuffer, 0, remaining);
103-
}
104-
105-
int bufLenSent = Math.min(0x00ffffff - sent, len);
106-
deflater.write(b, off, bufLenSent);
107-
sent += bufLenSent;
108-
deflater.finish();
81+
// *******************************************************************************
82+
// compressing packet
83+
// *******************************************************************************
84+
int sent = 0;
85+
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
86+
try (DeflaterOutputStream deflater = new DeflaterOutputStream(baos)) {
87+
88+
/**
89+
* For multi packet, len will be 0x00ffffff + 4 bytes for header. but compression can only
90+
* compress up to 0x00ffffff bytes (header initial length size cannot be > 3 bytes) so,
91+
* for this specific case, a buffer will save remaining data
92+
*/
93+
if (longPacketBuffer != null) {
94+
deflater.write(longPacketBuffer, 0, longPacketBuffer.length);
95+
sent = longPacketBuffer.length;
96+
longPacketBuffer = null;
97+
}
98+
if (len + sent > 0x00ffffff) {
99+
int remaining = len + sent - 0x00ffffff;
100+
longPacketBuffer = new byte[remaining];
101+
System.arraycopy(b, off + 0x00ffffff - sent, longPacketBuffer, 0, remaining);
109102
}
110103

111-
byte[] compressedBytes = baos.toByteArray();
104+
int bufLenSent = Math.min(0x00ffffff - sent, len);
105+
deflater.write(b, off, bufLenSent);
106+
sent += bufLenSent;
107+
deflater.finish();
108+
}
112109

113-
int compressLen = compressedBytes.length;
110+
byte[] compressedBytes = baos.toByteArray();
114111

115-
header[0] = (byte) compressLen;
116-
header[1] = (byte) (compressLen >>> 8);
117-
header[2] = (byte) (compressLen >>> 16);
118-
header[3] = sequence.incrementAndGet();
119-
header[4] = (byte) sent;
120-
header[5] = (byte) (sent >>> 8);
121-
header[6] = (byte) (sent >>> 16);
112+
int compressLen = compressedBytes.length;
122113

123-
out.write(header, 0, 7);
124-
out.write(compressedBytes, 0, compressLen);
125-
}
114+
header[0] = (byte) compressLen;
115+
header[1] = (byte) (compressLen >>> 8);
116+
header[2] = (byte) (compressLen >>> 16);
117+
header[3] = sequence.incrementAndGet();
118+
header[4] = (byte) sent;
119+
header[5] = (byte) (sent >>> 8);
120+
header[6] = (byte) (sent >>> 16);
121+
122+
out.write(header, 0, 7);
123+
out.write(compressedBytes, 0, compressLen);
124+
}
126125
}
127126
}
128127

src/main/java/org/mariadb/jdbc/codec/BinaryRowDecoder.java

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,13 @@ public double decodeDouble() throws SQLException {
6262
@Override
6363
public void setRow(byte[] buf) {
6464
if (buf != null) {
65-
this.readBuf.buf(buf, buf.length).pos(1); // skip 0x00 header
6665
nullBitmap = new byte[(columnCount + 9) / 8];
67-
this.readBuf.readBytes(nullBitmap).mark();
66+
for (int i = 0; i < nullBitmap.length; i++) {
67+
nullBitmap[i] = buf[i + 1];
68+
}
69+
this.readBuf.buf(buf, buf.length, 1 + nullBitmap.length);
6870
} else {
69-
this.readBuf.buf(null, 0);
71+
this.readBuf.buf(null, 0, 0);
7072
}
7173
index = -1;
7274
}
@@ -86,7 +88,8 @@ public void setPosition(int newIndex) {
8688

8789
if (index >= newIndex) {
8890
index = 0;
89-
readBuf.reset();
91+
// skip header + null-bitmap
92+
readBuf.pos(1 + ((columnCount + 9) / 8));
9093
} else {
9194
index++;
9295
}
@@ -116,8 +119,13 @@ public void setPosition(int newIndex) {
116119
break;
117120

118121
default:
119-
int type = this.readBuf.readUnsignedByte();
120-
switch (type) {
122+
int len = this.readBuf.readUnsignedByte();
123+
if (len < 251) {
124+
// length is encoded on 1 bytes (is then less than 251)
125+
this.readBuf.skip(len);
126+
break;
127+
}
128+
switch (len) {
121129
case 252:
122130
this.readBuf.skip(this.readBuf.readUnsignedShort());
123131
break;
@@ -129,18 +137,14 @@ public void setPosition(int newIndex) {
129137
case 254:
130138
this.readBuf.skip((int) this.readBuf.readLong());
131139
break;
132-
133-
default:
134-
this.readBuf.skip(type);
135-
break;
136140
}
137141
break;
138142
}
139143
}
140144
index++;
141145
}
142146

143-
if ((nullBitmap[(index + 2) / 8] & (1 << ((index + 2) % 8))) > 0) {
147+
if (wasNull()) {
144148
length = NULL_LENGTH;
145149
return;
146150
}
@@ -170,6 +174,11 @@ public void setPosition(int newIndex) {
170174
default:
171175
// field with variable length
172176
int len = this.readBuf.readUnsignedByte();
177+
if (len < 251) {
178+
// length is encoded on 1 bytes (is then less than 251)
179+
length = len;
180+
return;
181+
}
173182
switch (len) {
174183
case 252:
175184
// length is encoded on 3 bytes (0xfc header + 2 bytes indicating length)
@@ -185,10 +194,6 @@ public void setPosition(int newIndex) {
185194
// length is encoded on 9 bytes (0xfe header + 8 bytes indicating length)
186195
length = (int) this.readBuf.readLong();
187196
return;
188-
189-
default:
190-
// length is encoded on 1 bytes (is then less than 251)
191-
length = len;
192197
}
193198
}
194199
}

src/main/java/org/mariadb/jdbc/codec/RowDecoder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public RowDecoder(int columnCount, Column[] columns, Configuration conf) {
3131
}
3232

3333
public void setRow(byte[] buf) {
34-
this.readBuf.buf(buf, buf == null ? 0 : buf.length).pos(0);
34+
this.readBuf.buf(buf, buf == null ? 0 : buf.length, 0);
3535
index = -1;
3636
}
3737

src/main/java/org/mariadb/jdbc/codec/TextRowDecoder.java

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -77,28 +77,35 @@ public void setPosition(int newIndex) {
7777
}
7878

7979
while (index < newIndex) {
80-
short type = this.readBuf.readUnsignedByte();
81-
switch (type) {
82-
case 252:
83-
readBuf.skip(readBuf.readUnsignedShort());
84-
break;
85-
case 253:
86-
readBuf.skip(readBuf.readUnsignedMedium());
87-
break;
88-
case 254:
89-
readBuf.skip((int) (4 + readBuf.readUnsignedInt()));
90-
break;
91-
case 251:
92-
break;
93-
default:
94-
readBuf.skip(type);
95-
break;
80+
short len = this.readBuf.readUnsignedByte();
81+
if (len < 251) {
82+
// length is encoded on 1 bytes (is then less than 251)
83+
readBuf.skip(len);
84+
} else {
85+
switch (len) {
86+
case 252:
87+
readBuf.skip(readBuf.readUnsignedShort());
88+
break;
89+
case 253:
90+
readBuf.skip(readBuf.readUnsignedMedium());
91+
break;
92+
case 254:
93+
readBuf.skip((int) (4 + readBuf.readUnsignedInt()));
94+
break;
95+
case 251:
96+
break;
97+
}
9698
}
9799
index++;
98100
}
99101

100-
short type = this.readBuf.readUnsignedByte();
101-
switch (type) {
102+
short len = this.readBuf.readUnsignedByte();
103+
if (len < 251) {
104+
// length is encoded on 1 bytes (is then less than 251)
105+
length = len;
106+
return;
107+
}
108+
switch (len) {
102109
case 251:
103110
length = NULL_LENGTH;
104111
break;
@@ -112,9 +119,6 @@ public void setPosition(int newIndex) {
112119
length = (int) readBuf.readUnsignedInt();
113120
readBuf.skip(4);
114121
break;
115-
default:
116-
length = type;
117-
break;
118122
}
119123
}
120124
}

src/test/java/org/mariadb/jdbc/integration/CompressTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import org.junit.jupiter.api.*;
1111
import org.mariadb.jdbc.Connection;
1212
import org.mariadb.jdbc.Statement;
13-
import org.mariadb.jdbc.util.constants.Capabilities;
1413

1514
public class CompressTest extends Common {
1615
private static Connection shareCompressCon;
@@ -43,7 +42,8 @@ public void bigSend() throws SQLException {
4342
}
4443

4544
public void bigSend(Connection con, int maxLen) throws SQLException {
46-
char[] arr2 = new char[Math.min(maxLen, Math.min(16 * 1024 * 1024, (getMaxAllowedPacket() / 2) - 1000))];
45+
char[] arr2 =
46+
new char[Math.min(maxLen, Math.min(16 * 1024 * 1024, (getMaxAllowedPacket() / 2) - 1000))];
4747
for (int pos = 0; pos < arr2.length; pos++) {
4848
arr2[pos] = (char) ('A' + (pos % 60));
4949
}

0 commit comments

Comments
 (0)