From 581b51edd09040816051e4abc36c98e0534c73ff Mon Sep 17 00:00:00 2001 From: Warren James Date: Fri, 9 Jun 2023 11:31:17 -0400 Subject: [PATCH 01/12] chore(NODE-4283): update benchmark tooling --- etc/benchmarks/bson_versions.json | 10 +++ etc/benchmarks/convert_to_csv.sh | 57 ++++++++++++++ etc/benchmarks/install_bson_versions.sh | 10 +++ etc/benchmarks/lib_runner.mjs | 99 ++++++++++++------------- 4 files changed, 124 insertions(+), 52 deletions(-) create mode 100644 etc/benchmarks/bson_versions.json create mode 100755 etc/benchmarks/convert_to_csv.sh create mode 100755 etc/benchmarks/install_bson_versions.sh diff --git a/etc/benchmarks/bson_versions.json b/etc/benchmarks/bson_versions.json new file mode 100644 index 00000000..7058882f --- /dev/null +++ b/etc/benchmarks/bson_versions.json @@ -0,0 +1,10 @@ +{ + "versions": [ + "1.1.6", + "4.6", + "5.0", + "5.1", + "5.2", + "5.3" + ] +} diff --git a/etc/benchmarks/convert_to_csv.sh b/etc/benchmarks/convert_to_csv.sh new file mode 100755 index 00000000..d10500f6 --- /dev/null +++ b/etc/benchmarks/convert_to_csv.sh @@ -0,0 +1,57 @@ +#!/bin/bash +usage='./convert_to_csv.sh []' +input=$1 +output=$2 + +if [ -z $1 ]; then + echo "Usage: " $usage +fi + +if [ -z $output ]; then + output=results.csv +fi + +script=$(tempfile) +/bin/cat < $script + # delete first 7 lines + 1,7d + + # delete skipped tests + /skipped/D + + # delete total time + /Total time taken to benchmark/D + + # delete horizontal lines + /-------------/d + + # filter for lines that contain the max field + /^.*max.*\$/h + + # remove spaces + s/ //g + + # replace pipes with commas + y/|/,/ + + # remove trailing and leading comma + s/^,(.*),\$/\1/ + + # remove field names + s/([a-zA-Z0-9]+:)//g + + # remove units + s/([0-9]+)ms/\1/g + + # split version and test + s/---/,/ + P +EOM +lines=$(sed --quiet --regexp-extended -f $script < $input) + +echo 'version,test,max,min,mean,stddev,p90,p95,p99' | tee $output +for line in $lines; do + echo $line | tee -a $output +done + +rm -rf $script diff --git a/etc/benchmarks/install_bson_versions.sh b/etc/benchmarks/install_bson_versions.sh new file mode 100755 index 00000000..31202195 --- /dev/null +++ b/etc/benchmarks/install_bson_versions.sh @@ -0,0 +1,10 @@ +#!/bin/bash +versions=$(jq '.versions' < bson_versions.json | sed -E 's/(\[|\]|,|")//g') +installVersions='' +for bson in $versions; do + versionNoDot=$(echo $bson | tr -d '.') + installVersions+=" bson${versionNoDot}@npm:bson@${bson}" +done + +set -o xtrace +npm install --no-save ${installVersions} diff --git a/etc/benchmarks/lib_runner.mjs b/etc/benchmarks/lib_runner.mjs index f0cea7c5..47b559ba 100644 --- a/etc/benchmarks/lib_runner.mjs +++ b/etc/benchmarks/lib_runner.mjs @@ -6,6 +6,7 @@ import { cpus, totalmem } from 'os'; import { exec as execCb } from 'child_process'; import { promisify, types } from 'util'; import { writeFile } from 'fs/promises'; +import * as semver from 'semver'; import v8Profiler from 'v8-profiler-next'; import chalk from 'chalk'; const exec = promisify(execCb); @@ -53,67 +54,60 @@ export function getCurrentLocalBSON(libs) { } export async function getLibs() { - return await Promise.all([ - (async () => { - const { stdout } = await exec('git rev-parse --short HEAD'); - const hash = stdout.trim(); + const bsonVersions = await readJSONFile('./bson_versions.json'); + const entries = bsonVersions.versions.map(async (version) => { + const bsonPath = `../../node_modules/bson${version.replaceAll('.', '')}`; + const packageVersion = (await readJSONFile(`${bsonPath}/package.json`)).version; + if (semver.lte(semver.coerce(version), '3.0.0')) { + const legacy = (await import(`${bsonPath}/index.js`)).default; return { - name: 'local', - lib: await import('../../lib/index.js'), - version: hash + name: version, + lib: { ...legacy, ...legacy.prototype }, + version: packageVersion }; - })(), - (async () => ({ - name: 'released', - lib: await import('../../node_modules/bson_latest/lib/bson.js'), - version: (await readJSONFile('../../node_modules/bson_latest/package.json')).version - }))(), - (async () => { - const legacyBSON = (await import('../../node_modules/bson_legacy/index.js')).default; + } else if (semver.gte(semver.coerce(version), '5.0.0')) { return { - name: 'previous major', - lib: { ...legacyBSON, ...legacyBSON.prototype }, - version: (await readJSONFile('../../node_modules/bson_legacy/package.json')).version + name: version, + lib: await import(`${bsonPath}/lib/bson.cjs`), + version: packageVersion }; - })() - // BSON-EXT is EOL so we do not need to keep testing it, and it has issues installing it - // in this no-save way on M1 currently that are not worth fixing. - // (async () => ({ - // name: 'bson-ext', - // lib: await import('../../node_modules/bson_ext/lib/index.js'), - // version: (await readJSONFile('../../node_modules/bson_ext/package.json')).version - // }))() - ]).catch(error => { - console.error(error); - console.error( - `Please run:\n${[ - 'npm run build', - 'npm install --no-save bson_ext@npm:bson-ext@4 bson_legacy@npm:bson@1 bson_latest@npm:bson@latest' - ].join('\n')}` - ); + } else { + return { + name: version, + lib: await import(`${bsonPath}/lib/bson.js`), + version: packageVersion + }; + } + }); + + entries.unshift({ + name: 'local', + lib: await import('../../lib/bson.cjs'), + version: (await readJSONFile('../../package.json')).version + }); + + return await Promise.all(entries).catch(e => { + console.error(e); + console.error('Run\n\tnpm run build\n\t,./etc/benchmarks/install_bson_versions.sh'); process.exit(1); }); } const printHistogram = (name, h) => { const makeReadableTime = nanoseconds => (nanoseconds / 1e6).toFixed(3).padStart(7, ' '); - console.log(); - console.log(chalk.green(name)); - console.log('-'.repeat(155)); - process.stdout.write(`| ${chalk.cyan('max')}: ${chalk.red(makeReadableTime(h.max))} ms |`); - process.stdout.write(` ${chalk.cyan('min')}: ${chalk.red(makeReadableTime(h.min))} ms |`); - process.stdout.write(` ${chalk.cyan('mean')}: ${chalk.red(makeReadableTime(h.mean))} ms |`); - process.stdout.write(` ${chalk.cyan('stddev')}: ${chalk.red(makeReadableTime(h.stddev))} ms |`); - process.stdout.write( - ` ${chalk.cyan('p90th')}: ${chalk.red(makeReadableTime(h.percentile(90)))} ms |` - ); - process.stdout.write( - ` ${chalk.cyan('p95th')}: ${chalk.red(makeReadableTime(h.percentile(95)))} ms |` - ); - process.stdout.write( + const line = [ + `| ${chalk.green(name.replaceAll(' ', '-'))} | ${chalk.cyan('max')}: ${chalk.red(makeReadableTime(h.max))} ms |`, + ` ${chalk.cyan('min')}: ${chalk.red(makeReadableTime(h.min))} ms |`, + ` ${chalk.cyan('mean')}: ${chalk.red(makeReadableTime(h.mean))} ms |`, + ` ${chalk.cyan('stddev')}: ${chalk.red(makeReadableTime(h.stddev))} ms |`, + ` ${chalk.cyan('p90th')}: ${chalk.red(makeReadableTime(h.percentile(90)))} ms |`, + ` ${chalk.cyan('p95th')}: ${chalk.red(makeReadableTime(h.percentile(95)))} ms |`, ` ${chalk.cyan('p99th')}: ${chalk.red(makeReadableTime(h.percentile(99)))} ms |` - ); - console.log('\n' + '-'.repeat(155)); + ].join(''); + console.log(); + console.log('-'.repeat(235)); + console.log(line); + console.log('-'.repeat(235)); }; /** @@ -134,11 +128,12 @@ export async function runner({ iterations, setup, name, run, skip }) { const BSONLibs = await getLibs(); const setupResult = setup?.(BSONLibs) ?? null; - console.log('-'.repeat(155)); + console.log('-'.repeat(235)); for (const bson of BSONLibs) { - const profileName = `${bson.name}_${name}`; + const profileName = `${bson.name}_${name.replaceAll(' ', '-')}`; v8Profiler.startProfiling(profileName, true); + v8Profiler.setGenerateType(1); const { histogram, thrownError } = await testPerformance(bson, [run, setupResult], iterations); if (thrownError != null) { console.log( From b4fd977f4d404f4c770a2cd65db7f668d62571b5 Mon Sep 17 00:00:00 2001 From: Warren James Date: Fri, 16 Jun 2023 16:37:28 -0400 Subject: [PATCH 02/12] chore: update script --- etc/benchmarks/convert_to_csv.sh | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/etc/benchmarks/convert_to_csv.sh b/etc/benchmarks/convert_to_csv.sh index d10500f6..522c65fa 100755 --- a/etc/benchmarks/convert_to_csv.sh +++ b/etc/benchmarks/convert_to_csv.sh @@ -1,18 +1,29 @@ #!/bin/bash -usage='./convert_to_csv.sh []' +# This script is meant to be used on the output of benchmark runs to generate a csv file that can be +# more easily ingested in google sheets or your spreadsheet/data anaylsis tool of choice +# note that you will also see the output of the csv file printed in the terminal +usage=$(/bin/cat < [] + + Arguments: + input - file to read from + output - file to output csv (if not provided defaults to 'results.csv') +EOM +) input=$1 output=$2 -if [ -z $1 ]; then - echo "Usage: " $usage +if [ -z $input ]; then + echo "$usage" + exit 1 fi if [ -z $output ]; then output=results.csv fi -script=$(tempfile) -/bin/cat < $script +sed_script=$(cat < Date: Wed, 21 Jun 2023 10:00:52 -0400 Subject: [PATCH 03/12] fix(NODE-5358): WIP --- src/parser/deserializer.ts | 2 +- src/utils/byte_utils.ts | 2 +- src/utils/node_byte_utils.ts | 6 +++--- src/utils/web_byte_utils.ts | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/parser/deserializer.ts b/src/parser/deserializer.ts index 7ffd3636..19d44da0 100644 --- a/src/parser/deserializer.ts +++ b/src/parser/deserializer.ts @@ -735,7 +735,7 @@ function getValidatedString( end: number, shouldValidateUtf8: boolean ) { - const value = ByteUtils.toUTF8(buffer.subarray(start, end)); + const value = ByteUtils.toUTF8(buffer, start, end); // if utf8 validation is on, do the check if (shouldValidateUtf8) { for (let i = 0; i < value.length; i++) { diff --git a/src/utils/byte_utils.ts b/src/utils/byte_utils.ts index 7c44b38a..2b504f9c 100644 --- a/src/utils/byte_utils.ts +++ b/src/utils/byte_utils.ts @@ -26,7 +26,7 @@ export type ByteUtils = { /** Create a Uint8Array containing utf8 code units from a string */ fromUTF8: (text: string) => Uint8Array; /** Create a string from utf8 code units */ - toUTF8: (buffer: Uint8Array) => string; + toUTF8: (buffer: Uint8Array, start?: number, end?: number) => string; /** Get the utf8 code unit count from a string if it were to be transformed to utf8 */ utf8ByteLength: (input: string) => number; /** Encode UTF8 bytes generated from `source` string into `destination` at byteOffset. Returns the number of bytes encoded. */ diff --git a/src/utils/node_byte_utils.ts b/src/utils/node_byte_utils.ts index 468acf89..50779923 100644 --- a/src/utils/node_byte_utils.ts +++ b/src/utils/node_byte_utils.ts @@ -5,7 +5,7 @@ type NodeJsBuffer = ArrayBufferView & Uint8Array & { write(string: string, offset: number, length: undefined, encoding: 'utf8'): number; copy(target: Uint8Array, targetStart: number, sourceStart: number, sourceEnd: number): number; - toString: (this: Uint8Array, encoding: NodeJsEncoding) => string; + toString: (this: Uint8Array, encoding: NodeJsEncoding, start?: number, end?: number) => string; equals: (this: Uint8Array, other: Uint8Array) => boolean; }; type NodeJsBufferConstructor = Omit & { @@ -125,8 +125,8 @@ export const nodeJsByteUtils = { return Buffer.from(text, 'utf8'); }, - toUTF8(buffer: Uint8Array): string { - return nodeJsByteUtils.toLocalBufferType(buffer).toString('utf8'); + toUTF8(buffer: Uint8Array, start?: number, end?: number): string { + return nodeJsByteUtils.toLocalBufferType(buffer).toString('utf8', start, end); }, utf8ByteLength(input: string): number { diff --git a/src/utils/web_byte_utils.ts b/src/utils/web_byte_utils.ts index 6e45f91e..b053f0bc 100644 --- a/src/utils/web_byte_utils.ts +++ b/src/utils/web_byte_utils.ts @@ -172,8 +172,8 @@ export const webByteUtils = { return new TextEncoder().encode(text); }, - toUTF8(uint8array: Uint8Array): string { - return new TextDecoder('utf8', { fatal: false }).decode(uint8array); + toUTF8(uint8array: Uint8Array, start?: number, end?: number): string { + return new TextDecoder('utf8', { fatal: false }).decode(uint8array.slice(start, end)); }, utf8ByteLength(input: string): number { From d61e3c82bb383e43a7a150ef10106f1e46548a65 Mon Sep 17 00:00:00 2001 From: Warren James Date: Thu, 22 Jun 2023 10:18:46 -0400 Subject: [PATCH 04/12] chore(NODE-5358): add new benchmarks --- etc/benchmarks/bson_versions.json | 3 --- etc/benchmarks/main.mjs | 29 ++++++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/etc/benchmarks/bson_versions.json b/etc/benchmarks/bson_versions.json index 7058882f..42fa8077 100644 --- a/etc/benchmarks/bson_versions.json +++ b/etc/benchmarks/bson_versions.json @@ -2,9 +2,6 @@ "versions": [ "1.1.6", "4.6", - "5.0", - "5.1", - "5.2", "5.3" ] } diff --git a/etc/benchmarks/main.mjs b/etc/benchmarks/main.mjs index 6a927cb6..e461b248 100644 --- a/etc/benchmarks/main.mjs +++ b/etc/benchmarks/main.mjs @@ -102,7 +102,7 @@ await runner({ /// nextBatch simulate /// nextBatch: [ { string * 20 } * 1000 ] /// Garbage call await runner({ - skip: false, + skip: true, name: 'deserialize a large batch of documents each with an array of many strings', iterations, setup(libs) { @@ -129,6 +129,33 @@ await runner({ } }); +await runner({ + skip: false, + name: 'deserialize a large batch of documents each with an array of many Int32s', + iterations, + setup(libs) { + const bson = libs[0].lib; + return bson.serialize({ + nextBatch: Array.from({ length: 1000 }, () => ({ + _id: new bson.ObjectId(), + arrayField: Array.from({ length: 100 }, (_, i) => i) + })) + }); + }, + async run(i, bson, document) { + await Promise.all( + Array.from( + { length: 100 }, + (_, i) => + new Promise(resolve => { + setTimeout(() => { + resolve(bson.lib.deserialize(document, { validation: { utf8: false } })); + }, 20); + }) + ) + ); + } +}); // End console.log( 'Total time taken to benchmark:', From 34c26bc5c2b93fa2543bede72860f4608a5db452 Mon Sep 17 00:00:00 2001 From: Warren James Date: Fri, 23 Jun 2023 10:17:59 -0400 Subject: [PATCH 05/12] chore(NODE-5358): set string benchmark to run --- etc/benchmarks/bson_versions.json | 1 - etc/benchmarks/main.mjs | 32 +++++++++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/etc/benchmarks/bson_versions.json b/etc/benchmarks/bson_versions.json index 42fa8077..1e61d11c 100644 --- a/etc/benchmarks/bson_versions.json +++ b/etc/benchmarks/bson_versions.json @@ -1,6 +1,5 @@ { "versions": [ - "1.1.6", "4.6", "5.3" ] diff --git a/etc/benchmarks/main.mjs b/etc/benchmarks/main.mjs index e461b248..6f48cb1f 100644 --- a/etc/benchmarks/main.mjs +++ b/etc/benchmarks/main.mjs @@ -102,7 +102,7 @@ await runner({ /// nextBatch simulate /// nextBatch: [ { string * 20 } * 1000 ] /// Garbage call await runner({ - skip: true, + skip: false, name: 'deserialize a large batch of documents each with an array of many strings', iterations, setup(libs) { @@ -130,7 +130,7 @@ await runner({ }); await runner({ - skip: false, + skip: true, name: 'deserialize a large batch of documents each with an array of many Int32s', iterations, setup(libs) { @@ -156,6 +156,34 @@ await runner({ ); } }); + +await runner({ + skip: true, + name: 'deserialize a large batch of documents each with an array of many Int64s', + iterations, + setup(libs) { + const bson = libs[0].lib; + return bson.serialize({ + nextBatch: Array.from({ length: 1000 }, () => ({ + _id: new bson.ObjectId(), + arrayField: Array.from({ length: 100 }, (_, i) => bson.Long.fromInt(i)) + })) + }); + }, + async run(i, bson, document) { + await Promise.all( + Array.from( + { length: 100 }, + (_, i) => + new Promise(resolve => { + setTimeout(() => { + resolve(bson.lib.deserialize(document, { validation: { utf8: false } })); + }, 20); + }) + ) + ); + } +}); // End console.log( 'Total time taken to benchmark:', From 319ccbedfc8cf59d3c57306eccdb16beaeb27dcf Mon Sep 17 00:00:00 2001 From: Warren James Date: Fri, 23 Jun 2023 10:20:06 -0400 Subject: [PATCH 06/12] chore(NODE-5358): update script --- etc/benchmarks/install_bson_versions.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/etc/benchmarks/install_bson_versions.sh b/etc/benchmarks/install_bson_versions.sh index 71a2f8f5..c8e966c8 100755 --- a/etc/benchmarks/install_bson_versions.sh +++ b/etc/benchmarks/install_bson_versions.sh @@ -1,5 +1,6 @@ #!/bin/bash -versions=$(jq '.versions' < bson_versions.json | sed -E 's/(\[|\]|,|")//g') +# To be run from repo root +versions=$(jq '.versions' < etc/benchmarks/bson_versions.json | sed -E 's/(\[|\]|,|")//g') installVersions='' for bson in $versions; do versionNoDot=$(echo $bson | tr -d '.') From 425ee50292c2969f40166b9c86f626a5fcd3d8f2 Mon Sep 17 00:00:00 2001 From: Warren James Date: Fri, 23 Jun 2023 15:27:45 -0400 Subject: [PATCH 07/12] fix(NODE-5358): remove toLocalBufferType call from node byteutils toUTF8 --- src/utils/node_byte_utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/node_byte_utils.ts b/src/utils/node_byte_utils.ts index 50779923..2662b0ee 100644 --- a/src/utils/node_byte_utils.ts +++ b/src/utils/node_byte_utils.ts @@ -126,7 +126,7 @@ export const nodeJsByteUtils = { }, toUTF8(buffer: Uint8Array, start?: number, end?: number): string { - return nodeJsByteUtils.toLocalBufferType(buffer).toString('utf8', start, end); + return (buffer as NodeJsBuffer).toString('utf8', start, end); }, utf8ByteLength(input: string): number { From 6f81f936c4ee3811e9982f3c7552b123a4b30501 Mon Sep 17 00:00:00 2001 From: Warren James Date: Fri, 30 Jun 2023 11:24:14 -0400 Subject: [PATCH 08/12] fix(NODE-5358): restore toLocalBufferType call and make start and end required --- src/utils/node_byte_utils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/node_byte_utils.ts b/src/utils/node_byte_utils.ts index 2662b0ee..214b1e39 100644 --- a/src/utils/node_byte_utils.ts +++ b/src/utils/node_byte_utils.ts @@ -125,8 +125,8 @@ export const nodeJsByteUtils = { return Buffer.from(text, 'utf8'); }, - toUTF8(buffer: Uint8Array, start?: number, end?: number): string { - return (buffer as NodeJsBuffer).toString('utf8', start, end); + toUTF8(buffer: Uint8Array, start: number, end: number): string { + return nodeJsByteUtils.toLocalBufferType(buffer).toString('utf8', start, end); }, utf8ByteLength(input: string): number { From 8d443393fb673d165e3c9f5f06107a55c37ab86e Mon Sep 17 00:00:00 2001 From: Warren James Date: Fri, 30 Jun 2023 11:24:45 -0400 Subject: [PATCH 09/12] refactor(NODE-5358): remove unneeded Buffer.subarray calls --- src/parser/deserializer.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/parser/deserializer.ts b/src/parser/deserializer.ts index 19d44da0..abb61046 100644 --- a/src/parser/deserializer.ts +++ b/src/parser/deserializer.ts @@ -236,7 +236,7 @@ function deserializeObject( if (i >= buffer.byteLength) throw new BSONError('Bad BSON Document: illegal CString'); // Represents the key - const name = isArray ? arrayIndex++ : ByteUtils.toUTF8(buffer.subarray(index, i)); + const name = isArray ? arrayIndex++ : ByteUtils.toUTF8(buffer, index, i); // shouldValidateKey is true if the key should be validated, false otherwise let shouldValidateKey = true; @@ -476,7 +476,7 @@ function deserializeObject( // If are at the end of the buffer there is a problem with the document if (i >= buffer.length) throw new BSONError('Bad BSON Document: illegal CString'); // Return the C string - const source = ByteUtils.toUTF8(buffer.subarray(index, i)); + const source = ByteUtils.toUTF8(buffer, index, i); // Create the regexp index = i + 1; @@ -489,7 +489,7 @@ function deserializeObject( // If are at the end of the buffer there is a problem with the document if (i >= buffer.length) throw new BSONError('Bad BSON Document: illegal CString'); // Return the C string - const regExpOptions = ByteUtils.toUTF8(buffer.subarray(index, i)); + const regExpOptions = ByteUtils.toUTF8(buffer, index, i); index = i + 1; // For each option add the corresponding one for javascript @@ -521,7 +521,7 @@ function deserializeObject( // If are at the end of the buffer there is a problem with the document if (i >= buffer.length) throw new BSONError('Bad BSON Document: illegal CString'); // Return the C string - const source = ByteUtils.toUTF8(buffer.subarray(index, i)); + const source = ByteUtils.toUTF8(buffer, index, i); index = i + 1; // Get the start search index @@ -533,7 +533,7 @@ function deserializeObject( // If are at the end of the buffer there is a problem with the document if (i >= buffer.length) throw new BSONError('Bad BSON Document: illegal CString'); // Return the C string - const regExpOptions = ByteUtils.toUTF8(buffer.subarray(index, i)); + const regExpOptions = ByteUtils.toUTF8(buffer, index, i); index = i + 1; // Set the object @@ -678,7 +678,7 @@ function deserializeObject( throw new BSONError('Invalid UTF-8 string in BSON document'); } } - const namespace = ByteUtils.toUTF8(buffer.subarray(index, index + stringSize - 1)); + const namespace = ByteUtils.toUTF8(buffer, index, index + stringSize - 1); // Update parse index position index = index + stringSize; From bf290998a78c369c1d9b23fb0e5d89f81d30598e Mon Sep 17 00:00:00 2001 From: Warren James Date: Fri, 30 Jun 2023 14:56:29 -0400 Subject: [PATCH 10/12] fix(NODE-5358): make start and end required --- src/binary.ts | 4 ++-- src/utils/byte_utils.ts | 2 +- src/utils/web_byte_utils.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/binary.ts b/src/binary.ts index f69f62bf..9b67fd31 100644 --- a/src/binary.ts +++ b/src/binary.ts @@ -223,8 +223,8 @@ export class Binary extends BSONValue { toString(encoding?: 'hex' | 'base64' | 'utf8' | 'utf-8'): string { if (encoding === 'hex') return ByteUtils.toHex(this.buffer); if (encoding === 'base64') return ByteUtils.toBase64(this.buffer); - if (encoding === 'utf8' || encoding === 'utf-8') return ByteUtils.toUTF8(this.buffer); - return ByteUtils.toUTF8(this.buffer); + if (encoding === 'utf8' || encoding === 'utf-8') return ByteUtils.toUTF8(this.buffer, 0, this.buffer.length); + return ByteUtils.toUTF8(this.buffer, 0, this.buffer.length); } /** @internal */ diff --git a/src/utils/byte_utils.ts b/src/utils/byte_utils.ts index 2b504f9c..41ec2c6a 100644 --- a/src/utils/byte_utils.ts +++ b/src/utils/byte_utils.ts @@ -26,7 +26,7 @@ export type ByteUtils = { /** Create a Uint8Array containing utf8 code units from a string */ fromUTF8: (text: string) => Uint8Array; /** Create a string from utf8 code units */ - toUTF8: (buffer: Uint8Array, start?: number, end?: number) => string; + toUTF8: (buffer: Uint8Array, start: number, end: number) => string; /** Get the utf8 code unit count from a string if it were to be transformed to utf8 */ utf8ByteLength: (input: string) => number; /** Encode UTF8 bytes generated from `source` string into `destination` at byteOffset. Returns the number of bytes encoded. */ diff --git a/src/utils/web_byte_utils.ts b/src/utils/web_byte_utils.ts index b053f0bc..cf93e43a 100644 --- a/src/utils/web_byte_utils.ts +++ b/src/utils/web_byte_utils.ts @@ -172,7 +172,7 @@ export const webByteUtils = { return new TextEncoder().encode(text); }, - toUTF8(uint8array: Uint8Array, start?: number, end?: number): string { + toUTF8(uint8array: Uint8Array, start: number, end: number): string { return new TextDecoder('utf8', { fatal: false }).decode(uint8array.slice(start, end)); }, From dd4a2a69b2c75a4f033e8f9b73044bb50ee4cb29 Mon Sep 17 00:00:00 2001 From: Warren James Date: Fri, 30 Jun 2023 15:29:41 -0400 Subject: [PATCH 11/12] style(NODE-5358): eslint --- src/binary.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/binary.ts b/src/binary.ts index 9b67fd31..ab22e5aa 100644 --- a/src/binary.ts +++ b/src/binary.ts @@ -223,7 +223,8 @@ export class Binary extends BSONValue { toString(encoding?: 'hex' | 'base64' | 'utf8' | 'utf-8'): string { if (encoding === 'hex') return ByteUtils.toHex(this.buffer); if (encoding === 'base64') return ByteUtils.toBase64(this.buffer); - if (encoding === 'utf8' || encoding === 'utf-8') return ByteUtils.toUTF8(this.buffer, 0, this.buffer.length); + if (encoding === 'utf8' || encoding === 'utf-8') + return ByteUtils.toUTF8(this.buffer, 0, this.buffer.length); return ByteUtils.toUTF8(this.buffer, 0, this.buffer.length); } From 501a4657730dd1bd416e7784e6f3941d871c14c1 Mon Sep 17 00:00:00 2001 From: Warren James Date: Fri, 30 Jun 2023 15:38:35 -0400 Subject: [PATCH 12/12] style(NODE-5358): use buffer.byteLength --- src/binary.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/binary.ts b/src/binary.ts index ab22e5aa..1324fd41 100644 --- a/src/binary.ts +++ b/src/binary.ts @@ -224,8 +224,8 @@ export class Binary extends BSONValue { if (encoding === 'hex') return ByteUtils.toHex(this.buffer); if (encoding === 'base64') return ByteUtils.toBase64(this.buffer); if (encoding === 'utf8' || encoding === 'utf-8') - return ByteUtils.toUTF8(this.buffer, 0, this.buffer.length); - return ByteUtils.toUTF8(this.buffer, 0, this.buffer.length); + return ByteUtils.toUTF8(this.buffer, 0, this.buffer.byteLength); + return ByteUtils.toUTF8(this.buffer, 0, this.buffer.byteLength); } /** @internal */