Skip to content

Commit e6de40a

Browse files
committed
wip
1 parent cb38894 commit e6de40a

File tree

5 files changed

+62
-32
lines changed

5 files changed

+62
-32
lines changed

src/cmap/wire_protocol/on_demand/document.ts

+8-3
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,13 @@ export class OnDemandDocument {
8080

8181
if (name.length !== nameLength) return false;
8282

83-
for (let i = 0; i < name.length; i++) {
84-
if (this.bson[nameOffset + i] !== name.charCodeAt(i)) return false;
83+
const nameEnd = nameOffset + nameLength;
84+
for (
85+
let byteIndex = nameOffset, charIndex = 0;
86+
charIndex < name.length && byteIndex < nameEnd;
87+
charIndex++, byteIndex++
88+
) {
89+
if (this.bson[byteIndex] !== name.charCodeAt(charIndex)) return false;
8590
}
8691

8792
return true;
@@ -127,7 +132,7 @@ export class OnDemandDocument {
127132
const element = this.elements[index];
128133

129134
// skip this element if it has already been associated with a name
130-
if (!this.indexFound[index] && this.isElementName(name, element)) {
135+
if (!(index in this.indexFound) && this.isElementName(name, element)) {
131136
const cachedElement = { element, value: undefined };
132137
this.cache[name] = cachedElement;
133138
this.indexFound[index] = true;

src/cmap/wire_protocol/responses.ts

+25-25
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
type Document,
66
Long,
77
parseToElementsToArray,
8+
pluckBSONSerializeOptions,
89
type Timestamp
910
} from '../../bson';
1011
import { MongoUnexpectedServerResponseError } from '../../error';
@@ -153,13 +154,7 @@ export class MongoDBResponse extends OnDemandDocument {
153154

154155
public override toObject(options?: BSONSerializeOptions): Record<string, any> {
155156
const exactBSONOptions = {
156-
useBigInt64: options?.useBigInt64,
157-
promoteLongs: options?.promoteLongs,
158-
promoteValues: options?.promoteValues,
159-
promoteBuffers: options?.promoteBuffers,
160-
bsonRegExp: options?.bsonRegExp,
161-
raw: options?.raw ?? false,
162-
fieldsAsRaw: options?.fieldsAsRaw ?? {},
157+
...pluckBSONSerializeOptions(options ?? {}),
163158
validation: this.parseBsonSerializationOptions(options)
164159
};
165160
return super.toObject(exactBSONOptions);
@@ -188,33 +183,38 @@ export class CursorResponse extends MongoDBResponse {
188183
return value instanceof CursorResponse || value === CursorResponse.emptyGetMore;
189184
}
190185

191-
public id: Long;
192-
public ns: MongoDBNamespace | null = null;
193-
public batchSize = 0;
194-
195-
private batch: OnDemandDocument;
186+
private _batch: OnDemandDocument | null = null;
196187
private iterated = 0;
197188

198-
constructor(bytes: Uint8Array, offset?: number, isArray?: boolean) {
199-
super(bytes, offset, isArray);
189+
get cursor() {
190+
return this.get('cursor', BSONType.object, true);
191+
}
200192

201-
const cursor = this.get('cursor', BSONType.object, true);
193+
get id(): Long {
194+
return Long.fromBigInt(this.cursor.get('id', BSONType.long, true));
195+
}
202196

203-
const id = cursor.get('id', BSONType.long, true);
204-
this.id = new Long(Number(id & 0xffff_ffffn), Number((id >> 32n) & 0xffff_ffffn));
197+
get ns() {
198+
const namespace = this.cursor.get('ns', BSONType.string);
199+
if (namespace != null) return ns(namespace);
200+
return null;
201+
}
205202

206-
const namespace = cursor.get('ns', BSONType.string);
207-
if (namespace != null) this.ns = ns(namespace);
203+
get length() {
204+
return Math.max(this.batchSize - this.iterated, 0);
205+
}
208206

209-
if (cursor.has('firstBatch')) this.batch = cursor.get('firstBatch', BSONType.array, true);
210-
else if (cursor.has('nextBatch')) this.batch = cursor.get('nextBatch', BSONType.array, true);
207+
get batch() {
208+
if (this._batch != null) return this._batch;
209+
const cursor = this.cursor;
210+
if (cursor.has('firstBatch')) this._batch = cursor.get('firstBatch', BSONType.array, true);
211+
else if (cursor.has('nextBatch')) this._batch = cursor.get('nextBatch', BSONType.array, true);
211212
else throw new MongoUnexpectedServerResponseError('Cursor document did not contain a batch');
212-
213-
this.batchSize = this.batch.size();
213+
return this._batch;
214214
}
215215

216-
get length() {
217-
return Math.max(this.batchSize - this.iterated, 0);
216+
get batchSize() {
217+
return this.batch?.size();
218218
}
219219

220220
shift(options?: BSONSerializeOptions): any {

src/cursor/abstract_cursor.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ export abstract class AbstractCursor<
302302
return bufferedDocs;
303303
}
304304

305-
async *[Symbol.asyncIterator](): AsyncGenerator<TSchema, void, void> {
305+
private async *asyncIterator() {
306306
if (this.closed) {
307307
return;
308308
}
@@ -350,6 +350,10 @@ export abstract class AbstractCursor<
350350
}
351351
}
352352

353+
async *[Symbol.asyncIterator](): AsyncGenerator<TSchema, void, void> {
354+
yield* this.asyncIterator();
355+
}
356+
353357
stream(options?: CursorStreamOptions): Readable & AsyncIterable<TSchema> {
354358
if (options?.transform) {
355359
const transform = options.transform;

test/benchmarks/driverBench/index.js

+17-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,26 @@
11
'use strict';
22

33
const MongoBench = require('../mongoBench');
4+
const process = require('node:process');
45
const os = require('node:os');
6+
const util = require('node:util');
7+
8+
const args = util.parseArgs({
9+
args: process.argv.slice(2),
10+
options: {
11+
grep: {
12+
short: 'g',
13+
type: 'string',
14+
required: false
15+
}
16+
}
17+
});
518

619
const Runner = MongoBench.Runner;
720

821
let bsonType = 'js-bson';
922
// TODO(NODE-4606): test against different driver configurations in CI
1023

11-
const { inspect } = require('util');
1224
const { writeFile } = require('fs/promises');
1325
const { makeParallelBenchmarks, makeSingleBench, makeMultiBench } = require('../mongoBench/suites');
1426

@@ -30,7 +42,9 @@ function average(arr) {
3042
return arr.reduce((x, y) => x + y, 0) / arr.length;
3143
}
3244

33-
const benchmarkRunner = new Runner()
45+
const benchmarkRunner = new Runner({
46+
grep: args.values.grep ?? null
47+
})
3448
.suite('singleBench', suite => makeSingleBench(suite))
3549
.suite('multiBench', suite => makeMultiBench(suite))
3650
.suite('parallel', suite => makeParallelBenchmarks(suite));
@@ -96,7 +110,7 @@ benchmarkRunner
96110
})
97111
.then(data => {
98112
const results = JSON.stringify(data, undefined, 2);
99-
console.log(inspect(data, { depth: Infinity, colors: true }));
113+
console.log(util.inspect(data, { depth: Infinity, colors: true }));
100114
return writeFile('results.json', results);
101115
})
102116
.catch(err => console.error(err));

test/benchmarks/mongoBench/runner.js

+7
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class Runner {
6363
console.log.apply(console, arguments);
6464
};
6565
this.children = {};
66+
this.grep = options.grep?.toLowerCase() ?? null;
6667
}
6768

6869
/**
@@ -124,6 +125,12 @@ class Runner {
124125
const result = {};
125126

126127
for (const [name, benchmark] of benchmarks) {
128+
if (this.grep != null) {
129+
if (!name.toLowerCase().includes(this.grep)) {
130+
result[name] = 0;
131+
continue;
132+
}
133+
}
127134
this.reporter(` Executing Benchmark "${name}"`);
128135
result[name] = await this._runBenchmark(benchmark);
129136
}

0 commit comments

Comments
 (0)