Skip to content

Commit

Permalink
[CONJS-279] method parser faster search
Browse files Browse the repository at this point in the history
  • Loading branch information
rusher committed Feb 20, 2024
1 parent c300740 commit fd7e6e6
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 56 deletions.
60 changes: 32 additions & 28 deletions lib/cmd/decoder/binary-decoder.js
Expand Up @@ -66,42 +66,25 @@ class BinaryDecoder {
static parser(col, opts) {
// set reader function read(col, packet, index, nullBitmap, opts, throwUnexpectedError)
// this permit for multi-row result-set to avoid resolving type parsing each data.
switch (col.columnType) {
case FieldType.TINY:
return col.signed() ? readTinyBinarySigned : readTinyBinaryUnsigned;

case FieldType.YEAR:
case FieldType.SHORT:
return col.signed() ? readShortBinarySigned : readShortBinaryUnsigned;

case FieldType.INT24:
return col.signed() ? readMediumBinarySigned : readMediumBinaryUnsigned;

case FieldType.INT:
return col.signed() ? readIntBinarySigned : readIntBinaryUnsigned;

case FieldType.FLOAT:
return readFloatBinary;

case FieldType.DOUBLE:
return readDoubleBinary;
// return constant parser (function not depending on column info other than type)
const defaultParser = col.signed()
? DEFAULT_SIGNED_PARSER_TYPE[col.columnType]
: DEFAULT_UNSIGNED_PARSER_TYPE[col.columnType];
if (defaultParser) return defaultParser;

// parser depending on column info
switch (col.columnType) {
case FieldType.BIGINT:
if (col.signed()) {
return opts.bigIntAsNumber || opts.supportBigNumbers ? readBigintAsIntBinarySigned : readBigintBinarySigned;
}
return opts.bigIntAsNumber || opts.supportBigNumbers ? readBigintAsIntBinaryUnsigned : readBigintBinaryUnsigned;

case FieldType.DATE:
return readDateBinary;

case FieldType.DATETIME:
case FieldType.TIMESTAMP:
return opts.dateStrings ? readTimestampStringBinary.bind(null, col.scale) : readTimestampBinary;

case FieldType.TIME:
return readTimeBinary;

case FieldType.DECIMAL:
case FieldType.NEWDECIMAL:
return col.scale === 0 ? readDecimalAsIntBinary : readDecimalBinary;
Expand All @@ -110,10 +93,6 @@ class BinaryDecoder {
let defaultVal = col.__getDefaultGeomVal();
return readGeometryBinary.bind(null, defaultVal);

case FieldType.JSON:
//for mysql only => parse string as JSON object
return readJsonBinary;

case FieldType.BIT:
if (col.columnLength === 1 && opts.bitOneIsBoolean) {
return readBitBinaryBoolean;
Expand All @@ -134,6 +113,7 @@ class BinaryDecoder {
}
}
}

const isNullBitmap = (index, nullBitmap) => {
return (nullBitmap[Math.floor((index + 2) / 8)] & (1 << (index + 2) % 8)) > 0;
};
Expand Down Expand Up @@ -277,3 +257,27 @@ const readBinarySet = (packet, opts, throwUnexpectedError, nullBitmap, index) =>
};
const readStringBinary = (packet, opts, throwUnexpectedError, nullBitmap, index) =>
isNullBitmap(index, nullBitmap) ? null : packet.readStringLengthEncoded();

const DEFAULT_SIGNED_PARSER_TYPE = Array(256);
DEFAULT_SIGNED_PARSER_TYPE[FieldType.TINY] = readTinyBinarySigned;
DEFAULT_SIGNED_PARSER_TYPE[FieldType.YEAR] = readShortBinarySigned;
DEFAULT_SIGNED_PARSER_TYPE[FieldType.SHORT] = readShortBinarySigned;
DEFAULT_SIGNED_PARSER_TYPE[FieldType.INT24] = readMediumBinarySigned;
DEFAULT_SIGNED_PARSER_TYPE[FieldType.INT] = readIntBinarySigned;
DEFAULT_SIGNED_PARSER_TYPE[FieldType.FLOAT] = readFloatBinary;
DEFAULT_SIGNED_PARSER_TYPE[FieldType.DOUBLE] = readDoubleBinary;
DEFAULT_SIGNED_PARSER_TYPE[FieldType.DATE] = readDateBinary;
DEFAULT_SIGNED_PARSER_TYPE[FieldType.TIME] = readTimeBinary;
DEFAULT_SIGNED_PARSER_TYPE[FieldType.JSON] = readJsonBinary;

const DEFAULT_UNSIGNED_PARSER_TYPE = Array(256);
DEFAULT_UNSIGNED_PARSER_TYPE[FieldType.TINY] = readTinyBinaryUnsigned;
DEFAULT_UNSIGNED_PARSER_TYPE[FieldType.YEAR] = readShortBinaryUnsigned;
DEFAULT_UNSIGNED_PARSER_TYPE[FieldType.SHORT] = readShortBinaryUnsigned;
DEFAULT_UNSIGNED_PARSER_TYPE[FieldType.INT24] = readMediumBinaryUnsigned;
DEFAULT_UNSIGNED_PARSER_TYPE[FieldType.INT] = readIntBinaryUnsigned;
DEFAULT_UNSIGNED_PARSER_TYPE[FieldType.FLOAT] = readFloatBinary;
DEFAULT_UNSIGNED_PARSER_TYPE[FieldType.DOUBLE] = readDoubleBinary;
DEFAULT_UNSIGNED_PARSER_TYPE[FieldType.DATE] = readDateBinary;
DEFAULT_UNSIGNED_PARSER_TYPE[FieldType.TIME] = readTimeBinary;
DEFAULT_UNSIGNED_PARSER_TYPE[FieldType.JSON] = readJsonBinary;
51 changes: 23 additions & 28 deletions lib/cmd/decoder/text-decoder.js
Expand Up @@ -50,48 +50,29 @@ class TextDecoder {
return packet.readGeometry(defaultVal);
};
}

static parser(col, opts) {
// set reader function read(col, packet, index, nullBitmap, opts, throwUnexpectedError)
// this permit for multi-row result-set to avoid resolving type parsing each data.

switch (col.columnType) {
case FieldType.TINY:
case FieldType.SHORT:
case FieldType.INT:
case FieldType.INT24:
case FieldType.YEAR:
return readIntLengthEncoded;

case FieldType.FLOAT:
case FieldType.DOUBLE:
return readFloatLengthCoded;

case FieldType.BIGINT:
if (opts.bigIntAsNumber || opts.supportBigNumbers) return readBigIntAsNumberLengthCoded;
return readBigIntLengthCoded;
// return constant parser (function not depending on column info other than type)
const defaultParser = DEFAULT_PARSER_TYPE[col.columnType];
if (defaultParser) return defaultParser;

// parser depending on column info
switch (col.columnType) {
case FieldType.DECIMAL:
case FieldType.NEWDECIMAL:
return col.scale === 0 ? readDecimalAsIntLengthCoded : readDecimalLengthCoded;

case FieldType.DATE:
return readDate;

case FieldType.DATETIME:
case FieldType.TIMESTAMP:
return readTimestamp;

case FieldType.TIME:
return readAsciiStringLengthEncoded;
case FieldType.BIGINT:
if (opts.bigIntAsNumber || opts.supportBigNumbers) return readBigIntAsNumberLengthCoded;
return readBigIntLengthCoded;

case FieldType.GEOMETRY:
let defaultVal = col.__getDefaultGeomVal();
return readGeometry.bind(null, defaultVal);

case FieldType.JSON:
//for mysql only => parse string as JSON object
return readJson;

case FieldType.BIT:
if (col.columnLength === 1 && opts.bitOneIsBoolean) {
return readBitAsBoolean;
Expand Down Expand Up @@ -201,3 +182,17 @@ const readSet = (packet, opts, throwUnexpectedError) => {
const string = packet.readStringLengthEncoded();
return string == null ? null : string === '' ? [] : string.split(',');
};

const DEFAULT_PARSER_TYPE = Array(256);
DEFAULT_PARSER_TYPE[FieldType.TINY] = readIntLengthEncoded;
DEFAULT_PARSER_TYPE[FieldType.SHORT] = readIntLengthEncoded;
DEFAULT_PARSER_TYPE[FieldType.INT] = readIntLengthEncoded;
DEFAULT_PARSER_TYPE[FieldType.INT24] = readIntLengthEncoded;
DEFAULT_PARSER_TYPE[FieldType.YEAR] = readIntLengthEncoded;
DEFAULT_PARSER_TYPE[FieldType.FLOAT] = readFloatLengthCoded;
DEFAULT_PARSER_TYPE[FieldType.DOUBLE] = readFloatLengthCoded;
DEFAULT_PARSER_TYPE[FieldType.DATE] = readDate;
DEFAULT_PARSER_TYPE[FieldType.DATETIME] = readTimestamp;
DEFAULT_PARSER_TYPE[FieldType.TIMESTAMP] = readTimestamp;
DEFAULT_PARSER_TYPE[FieldType.TIME] = readAsciiStringLengthEncoded;
DEFAULT_PARSER_TYPE[FieldType.JSON] = readJson;

0 comments on commit fd7e6e6

Please sign in to comment.