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-5955): use pooled memory when possible #653

Merged
merged 1 commit into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion src/bson.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export function serialize(object: Document, options: SerializeOptions = {}): Uin
);

// Create the final buffer
const finishedBuffer = ByteUtils.allocate(serializationIndex);
const finishedBuffer = ByteUtils.allocateUnsafe(serializationIndex);

// Copy into the finished buffer
finishedBuffer.set(buffer.subarray(0, serializationIndex), 0);
Expand Down
2 changes: 1 addition & 1 deletion src/decimal128.ts
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,7 @@ export class Decimal128 extends BSONValue {
}

// Encode into a buffer
const buffer = ByteUtils.allocate(16);
const buffer = ByteUtils.allocateUnsafe(16);
index = 0;

// Encode the low 64 bits of the decimal
Expand Down
2 changes: 1 addition & 1 deletion src/objectid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ export class ObjectId extends BSONValue {
}

const inc = ObjectId.getInc();
const buffer = ByteUtils.allocate(12);
const buffer = ByteUtils.allocateUnsafe(12);

// 4-byte timestamp
NumberUtils.setInt32BE(buffer, 0, time);
Expand Down
24 changes: 11 additions & 13 deletions src/parser/deserializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,8 +264,8 @@ function deserializeObject(
value = ByteUtils.toUTF8(buffer, index, index + stringSize - 1, shouldValidateKey);
index = index + stringSize;
} else if (elementType === constants.BSON_DATA_OID) {
const oid = ByteUtils.allocate(12);
oid.set(buffer.subarray(index, index + 12));
const oid = ByteUtils.allocateUnsafe(12);
for (let i = 0; i < 12; i++) oid[i] = buffer[index + i];
value = new ObjectId(oid);
index = index + 12;
} else if (elementType === constants.BSON_DATA_INT && promoteValues === false) {
Expand Down Expand Up @@ -355,9 +355,9 @@ function deserializeObject(
}
} else if (elementType === constants.BSON_DATA_DECIMAL128) {
// Buffer to contain the decimal bytes
const bytes = ByteUtils.allocate(16);
const bytes = ByteUtils.allocateUnsafe(16);
// Copy the next 16 bytes into the bytes buffer
bytes.set(buffer.subarray(index, index + 16), 0);
for (let i = 0; i < 16; i++) bytes[i] = buffer[index + i];
// Update index
index = index + 16;
// Assign the new Decimal128 value
Expand Down Expand Up @@ -398,7 +398,6 @@ function deserializeObject(
}
}
} else {
const _buffer = ByteUtils.allocate(binarySize);
// If we have subtype 2 skip the 4 bytes for the size
if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
binarySize = NumberUtils.getInt32LE(buffer, index);
Expand All @@ -411,13 +410,12 @@ function deserializeObject(
throw new BSONError('Binary type with subtype 0x02 contains too short binary size');
}

// Copy the data
for (i = 0; i < binarySize; i++) {
_buffer[i] = buffer[index + i];
}

if (promoteBuffers && promoteValues) {
value = _buffer;
value = ByteUtils.allocateUnsafe(binarySize);
// Copy the data
for (i = 0; i < binarySize; i++) {
value[i] = buffer[index + i];
}
} else {
value = new Binary(buffer.slice(index, index + binarySize), subType);
if (subType === constants.BSON_BINARY_SUBTYPE_UUID_NEW && UUID.isValid(value)) {
Expand Down Expand Up @@ -616,8 +614,8 @@ function deserializeObject(
index = index + stringSize;

// Read the oid
const oidBuffer = ByteUtils.allocate(12);
oidBuffer.set(buffer.subarray(index, index + 12), 0);
const oidBuffer = ByteUtils.allocateUnsafe(12);
for (let i = 0; i < 12; i++) oidBuffer[i] = buffer[index + i];
const oid = new ObjectId(oidBuffer);

// Update the index
Expand Down
2 changes: 2 additions & 0 deletions src/utils/byte_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ export type ByteUtils = {
toLocalBufferType(buffer: Uint8Array | ArrayBufferView | ArrayBuffer): Uint8Array;
/** Create empty space of size */
allocate: (size: number) => Uint8Array;
/** Create empty space of size, use pooled memory when available */
allocateUnsafe: (size: number) => Uint8Array;
/** Check if two Uint8Arrays are deep equal */
equals: (a: Uint8Array, b: Uint8Array) => boolean;
/** Check if two Uint8Arrays are deep equal */
Expand Down
5 changes: 5 additions & 0 deletions src/utils/node_byte_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type NodeJsBuffer = ArrayBufferView &
};
type NodeJsBufferConstructor = Omit<Uint8ArrayConstructor, 'from'> & {
alloc: (size: number) => NodeJsBuffer;
allocUnsafe: (size: number) => NodeJsBuffer;
from(array: number[]): NodeJsBuffer;
from(array: Uint8Array): NodeJsBuffer;
from(array: ArrayBuffer): NodeJsBuffer;
Expand Down Expand Up @@ -89,6 +90,10 @@ export const nodeJsByteUtils = {
return Buffer.alloc(size);
},

allocateUnsafe(size: number): NodeJsBuffer {
return Buffer.allocUnsafe(size);
},

equals(a: Uint8Array, b: Uint8Array): boolean {
return nodeJsByteUtils.toLocalBufferType(a).equals(b);
},
Expand Down
4 changes: 4 additions & 0 deletions src/utils/web_byte_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ export const webByteUtils = {
return new Uint8Array(size);
},

allocateUnsafe(size: number): Uint8Array {
return webByteUtils.allocate(size);
},

equals(a: Uint8Array, b: Uint8Array): boolean {
if (a.byteLength !== b.byteLength) {
return false;
Expand Down