Skip to content

Commit 4758b15

Browse files
committed
WIP compressed read
1 parent cadecf6 commit 4758b15

File tree

10 files changed

+330
-60
lines changed

10 files changed

+330
-60
lines changed

Readme.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,18 +1373,22 @@ The following flags are sent by default on a new connection:
13731373
- `SECURE_CONNECTION` - Support native 4.1 authentication.
13741374
- `TRANSACTIONS` - Asks for the transaction status flags.
13751375

1376-
In addition, the following flag will be sent if the option `multipleStatements`
1376+
The following flag will be sent if the option `multipleStatements`
13771377
is set to `true`:
13781378

13791379
- `MULTI_STATEMENTS` - The client may send multiple statement per query or
13801380
statement prepare.
13811381

1382+
The following flag will be sent if the option `compress` is set to `true`
1383+
and the server indicates support for compression:
1384+
1385+
- `COMPRESS` - Compress data between client and server.
1386+
13821387
### Other Available Flags
13831388

13841389
There are other flags available. They may or may not function, but are still
13851390
available to specify.
13861391

1387-
- `COMPRESS`
13881392
- `INTERACTIVE`
13891393
- `NO_SCHEMA`
13901394
- `PLUGIN_AUTH`

lib/ConnectionConfig.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ function ConnectionConfig(options) {
2222
this.insecureAuth = options.insecureAuth || false;
2323
this.supportBigNumbers = options.supportBigNumbers || false;
2424
this.bigNumberStrings = options.bigNumberStrings || false;
25+
this.compress = options.compress || false;
2526
this.dateStrings = options.dateStrings || false;
2627
this.debug = options.debug;
2728
this.trace = options.trace !== false;
@@ -95,7 +96,6 @@ ConnectionConfig.getCharsetNumber = function getCharsetNumber(charset) {
9596

9697
ConnectionConfig.getDefaultFlags = function getDefaultFlags(options) {
9798
var defaultFlags = [
98-
'-COMPRESS', // Compression protocol *NOT* supported
9999
'-CONNECT_ATTRS', // Does *NOT* send connection attributes in Protocol::HandshakeResponse41
100100
'+CONNECT_WITH_DB', // One can specify db on connect in Handshake Response Packet
101101
'+FOUND_ROWS', // Send found rows instead of affected rows

lib/protocol/BufferList.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,12 @@ BufferList.prototype.push = function push(buf) {
2323
this.bufs.push(buf);
2424
this.size += buf.length;
2525
};
26+
27+
BufferList.prototype.unshift = function unshift(buf) {
28+
if (!buf || !buf.length) {
29+
return;
30+
}
31+
32+
this.bufs.unshift(buf);
33+
this.size += buf.length;
34+
};
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
module.exports = CompressedPacketHeader;
2+
function CompressedPacketHeader(options) {
3+
options = options || {};
4+
5+
this.length = options.length || 0;
6+
this.sequence = options.sequence || 0;
7+
this.size = options.size || 0;
8+
}
9+
10+
CompressedPacketHeader.fromBuffer = function fromBuffer(buffer) {
11+
var length = 0;
12+
var offset = 0;
13+
var sequence = 0;
14+
var size = 0;
15+
16+
for (var i = 0; i < 3; i++) {
17+
length |= buffer[offset++] << (i * 8);
18+
}
19+
20+
sequence = buffer[offset++];
21+
22+
for (var i = 0; i < 3; i++) {
23+
size |= buffer[offset++] << (i * 8);
24+
}
25+
26+
return new CompressedPacketHeader({
27+
length : length,
28+
sequence : sequence,
29+
size : size
30+
});
31+
};

lib/protocol/PacketWriter.js

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
var BIT_16 = Math.pow(2, 16);
2-
var BIT_24 = Math.pow(2, 24);
3-
var BUFFER_ALLOC_SIZE = Math.pow(2, 8);
1+
var BIT_16 = Math.pow(2, 16);
2+
var BIT_24 = Math.pow(2, 24);
3+
var BUFFER_ALLOC_SIZE = Math.pow(2, 8);
4+
var COMPRESSED_PACKET_HEADER_LENGTH = 7;
45
// The maximum precision JS Numbers can hold precisely
56
// Don't panic: Good enough to represent byte values up to 8192 TB
67
var IEEE_754_BINARY_64_PRECISION = Math.pow(2, 53);
8+
var PACKET_HEADER_LENGTH = 4;
79
var MAX_PACKET_LENGTH = Math.pow(2, 24) - 1;
810
var Buffer = require('safe-buffer').Buffer;
911

@@ -22,8 +24,9 @@ PacketWriter.prototype.toBuffer = function toBuffer(parser) {
2224
var buffer = this._buffer;
2325
var length = this._offset;
2426
var packets = Math.floor(length / MAX_PACKET_LENGTH) + 1;
27+
var size = length + (packets * PACKET_HEADER_LENGTH);
2528

26-
this._buffer = Buffer.allocUnsafe(length + packets * 4);
29+
this._buffer = Buffer.allocUnsafe(size);
2730
this._offset = 0;
2831

2932
for (var packet = 0; packet < packets; packet++) {
@@ -43,6 +46,34 @@ PacketWriter.prototype.toBuffer = function toBuffer(parser) {
4346
this.writeBuffer(buffer.slice(start, end));
4447
}
4548

49+
if (parser._compressed) {
50+
buffer = this._buffer;
51+
length = this._offset;
52+
packets = Math.floor(length / MAX_PACKET_LENGTH) + 1;
53+
size = length + (packets * COMPRESSED_PACKET_HEADER_LENGTH);
54+
55+
this._buffer = Buffer.allocUnsafe(size);
56+
this._offset = 0;
57+
58+
for (packet = 0; packet < packets; packet++) {
59+
isLast = (packet + 1 === packets);
60+
packetLength = (isLast)
61+
? length % MAX_PACKET_LENGTH
62+
: MAX_PACKET_LENGTH;
63+
64+
packetNumber = parser.incrementCompressedPacketNumber();
65+
66+
this.writeUnsignedNumber(3, packetLength);
67+
this.writeUnsignedNumber(1, packetNumber);
68+
this.writeUnsignedNumber(3, 0);
69+
70+
var start = packet * MAX_PACKET_LENGTH;
71+
var end = start + packetLength;
72+
73+
this.writeBuffer(buffer.slice(start, end));
74+
}
75+
}
76+
4677
return this._buffer;
4778
};
4879

0 commit comments

Comments
 (0)