Skip to content

Commit fd1bbed

Browse files
committed
[misc] parsing performance improvement - part 2
1 parent 9e8134f commit fd1bbed

File tree

4 files changed

+24
-33
lines changed

4 files changed

+24
-33
lines changed

lib/io/packet-output-stream.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const MEDIUM_BUFFER_SIZE = 16384; //16k
1919
const LARGE_BUFFER_SIZE = 131072; //128k
2020
const BIG_BUFFER_SIZE = 1048576; //1M
2121
const MAX_BUFFER_SIZE = 16777219; //16M + 4
22-
const CHARS_GLOBAL_REGEXP = /[\0\"\'\\\b\n\r\t\u001A]/g; // eslint-disable-line no-control-regex
22+
const CHARS_GLOBAL_REGEXP = /[\000\032"'\\\n\r\t]/g;
2323

2424
/**
2525
* MySQL packet builder.
@@ -496,8 +496,9 @@ class PacketOutputStream {
496496
* - \\
497497
* - \'
498498
* - \"
499+
* - \032
499500
* regex split part of string writing part, and escaping special char.
500-
* Those chars are <= 7f meaning that this will work even with multi-byte encoding
501+
* Those chars are <= 7f meaning that this will work even with multibyte encoding
501502
*
502503
* @param str string to escape.
503504
*/
@@ -623,11 +624,11 @@ class PacketOutputStream {
623624
*
624625
* @param length additional length to query size
625626
* @param info current connection information
626-
* @throws Error if query has not to be send.
627+
* @throws Error if query has not to be sent.
627628
*/
628629
checkMaxAllowedLength(length, info) {
629630
if (this.cmdLength + length >= this.maxAllowedPacket) {
630-
// launch exception only if no packet has been send.
631+
// launch exception only if no packet has been sent.
631632
return Errors.createFatalError(
632633
`query size (${this.cmdLength + length}) is >= to max_allowed_packet (${this.maxAllowedPacket})`,
633634
Errors.ER_MAX_ALLOWED_PACKET,

lib/io/packet.js

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ class Packet {
248248

249249
readSignedLengthBigInt() {
250250
const type = this.buf[this.pos++];
251+
if (type < 0xfb) return BigInt(type);
251252
switch (type) {
252253
// null test is not used for now, since only used for reading insertId
253254
// case 0xfb:
@@ -258,8 +259,6 @@ class Packet {
258259
return BigInt(this.readUInt24());
259260
case 0xfe:
260261
return this.readBigInt64();
261-
default:
262-
return BigInt(type);
263262
}
264263
}
265264

@@ -276,17 +275,18 @@ class Packet {
276275

277276
readBigIntLengthEncoded() {
278277
const len = this.buf[this.pos++];
279-
if (len === 0xfb) return null;
280-
return this.readBigIntFromLen(len);
281-
}
282278

283-
readBigIntFromLen(len) {
284-
// fast-path: if length encoded is < to 16, value is in safe integer range
285-
// atoi
279+
// fast-path: if length encoded is < to 16, value is in safe integer range, using atoi
286280
if (len < 16) {
287281
return BigInt(this._atoi(len));
288282
}
289283

284+
if (len === 0xfb) return null;
285+
286+
return this.readBigIntFromLen(len);
287+
}
288+
289+
readBigIntFromLen(len) {
290290
// atoll
291291
let result = 0n;
292292
let negate = false;
@@ -493,18 +493,8 @@ class Packet {
493493

494494
readIntLengthEncoded() {
495495
const len = this.buf[this.pos++];
496-
if (len < 0xfb) return this._atoi(len);
497-
switch (len) {
498-
case 0xfb:
499-
return null;
500-
case 0xfc:
501-
return this._atoi(this.readUInt16());
502-
case 0xfd:
503-
return this._atoi(this.readUInt24());
504-
case 0xfe:
505-
// limitation to BigInt signed value
506-
return this._atoi(Number(this.readBigInt64()));
507-
}
496+
if (len === 0xfb) return null;
497+
return this._atoi(len);
508498
}
509499

510500
_atoi(len) {
@@ -537,7 +527,7 @@ class Packet {
537527
case 251:
538528
return;
539529
case 252:
540-
this.pos += 2 + (0xffff & ((this.buf[this.pos]) + ((this.buf[this.pos + 1]) << 8)));
530+
this.pos += 2 + (0xffff & (this.buf[this.pos] + (this.buf[this.pos + 1] << 8)));
541531
return;
542532
case 253:
543533
this.pos +=

lib/misc/utils.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,17 +243,17 @@ const LITTERAL_ESCAPE = {
243243
'\\': '\\\\'
244244
};
245245

246-
const escapeString = (val) => {
247-
const pattern = /[\u0000'"\b\n\r\t\u001A\\]/g;
246+
const CHARS_GLOBAL_REGEXP = /[\000\032"'\\\b\n\r\t]/g;
248247

248+
const escapeString = (val) => {
249249
let offset = 0;
250250
let escaped = '';
251251
let match;
252252

253-
while ((match = pattern.exec(val))) {
253+
while ((match = CHARS_GLOBAL_REGEXP.exec(val))) {
254254
escaped += val.substring(offset, match.index);
255255
escaped += LITTERAL_ESCAPE[match[0]];
256-
offset = pattern.lastIndex;
256+
offset = CHARS_GLOBAL_REGEXP.lastIndex;
257257
}
258258

259259
if (offset === 0) {

test/integration/datatype/test-buffer.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ describe('buffer', () => {
2222
const hex = buf.toString('hex').toUpperCase();
2323

2424
it('buffer escape', async function () {
25-
const buf = Buffer.from(base.utf8Collation() ? "let's rocks\n😊 🤘" : "let's rocks\nmore simple");
25+
const buf = Buffer.from(base.utf8Collation() ? "let's r\0cks\n😊 🤘" : "let's r\0cks\nmore simple");
2626
assert.equal(
2727
shareConn.escape(buf),
28-
base.utf8Collation() ? "_binary'let\\'s rocks\\n😊 🤘'" : "_binary'let\\'s rocks\\nmore simple'"
28+
base.utf8Collation() ? "_binary'let\\'s r\\0cks\\n😊 🤘'" : "_binary'let\\'s r\\0cks\\nmore simple'"
2929
);
3030
await shareConn.query('DROP TABLE IF EXISTS BufEscape');
3131
await shareConn.query('CREATE TABLE BufEscape(b blob)');
@@ -38,10 +38,10 @@ describe('buffer', () => {
3838
});
3939

4040
it('buffer escape binary', async function () {
41-
const buf = Buffer.from(base.utf8Collation() ? "let's rocks\n😊 🤘" : "let's rocks\nmore simple");
41+
const buf = Buffer.from(base.utf8Collation() ? "let's r\0cks\n😊 🤘" : "let's r\0cks\nmore simple");
4242
assert.equal(
4343
shareConn.escape(buf),
44-
base.utf8Collation() ? "_binary'let\\'s rocks\\n😊 🤘'" : "_binary'let\\'s rocks\\nmore simple'"
44+
base.utf8Collation() ? "_binary'let\\'s r\\0cks\\n😊 🤘'" : "_binary'let\\'s r\\0cks\\nmore simple'"
4545
);
4646
await shareConn.query('DROP TABLE IF EXISTS BufEscape');
4747
await shareConn.query('CREATE TABLE BufEscape(b blob)');

0 commit comments

Comments
 (0)