Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf(NODE-5557): move DataView and Set allocation used for double parsing and utf8 validation to nested path #611

Merged
merged 2 commits into from
Feb 14, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions src/parser/deserializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ function deserializeObject(
// Reflects utf-8 validation setting regardless of global or specific key validation
let validationSetting: boolean;
// Set of keys either to enable or disable validation on
const utf8KeysSet = new Set();
let utf8KeysSet;

// Check for boolean uniformity and empty validation option
const utf8ValidatedKeys = validation.utf8;
Expand All @@ -190,6 +190,8 @@ function deserializeObject(

// Add keys to set that will either be validated or not based on validationSetting
if (!globalUTFValidation) {
utf8KeysSet = new Set();

for (const key of Object.keys(utf8ValidatedKeys)) {
utf8KeysSet.add(key);
}
Expand All @@ -216,8 +218,9 @@ function deserializeObject(

let isPossibleDBRef = isArray ? false : null;

let dataView;

// While we have more left data left keep parsing
const dataview = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
while (!done) {
// Read the type
const elementType = buffer[index++];
Expand All @@ -240,7 +243,7 @@ function deserializeObject(

// shouldValidateKey is true if the key should be validated, false otherwise
let shouldValidateKey = true;
if (globalUTFValidation || utf8KeysSet.has(name)) {
if (globalUTFValidation || utf8KeysSet?.has(name)) {
shouldValidateKey = validationSetting;
} else {
shouldValidateKey = !validationSetting;
Expand Down Expand Up @@ -284,10 +287,12 @@ function deserializeObject(
(buffer[index++] << 16) |
(buffer[index++] << 24);
} else if (elementType === constants.BSON_DATA_NUMBER && promoteValues === false) {
value = new Double(dataview.getFloat64(index, true));
dataView ??= new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
value = new Double(dataView.getFloat64(index, true));
index = index + 8;
} else if (elementType === constants.BSON_DATA_NUMBER) {
value = dataview.getFloat64(index, true);
dataView ??= new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
value = dataView.getFloat64(index, true);
index = index + 8;
} else if (elementType === constants.BSON_DATA_DATE) {
const lowBits =
Expand All @@ -300,6 +305,7 @@ function deserializeObject(
(buffer[index++] << 8) |
(buffer[index++] << 16) |
(buffer[index++] << 24);

value = new Date(new Long(lowBits, highBits).toNumber());
} else if (elementType === constants.BSON_DATA_BOOLEAN) {
if (buffer[index] !== 0 && buffer[index] !== 1)
Expand Down