@@ -4,23 +4,28 @@ import { type InspectFn, defaultInspect } from './parser/utils';
4
4
import { ByteUtils } from './utils/byte_utils' ;
5
5
import { NumberUtils } from './utils/number_utils' ;
6
6
7
- const defaultPoolSize = 1000 ; // Hold 1000 ObjectId buffers in a pool
8
- let pool : Uint8Array ;
9
- let poolOffset = 0 ;
7
+ let currentPool : Uint8Array | null = null ;
8
+ let poolSize = 1000 ; // Default: Hold 1000 ObjectId buffers in a pool
9
+ let currentPoolOffset = 0 ;
10
10
11
- /** Internal pool accessors for objectId instance */
12
- /** @internal private instance pool accessor */
13
- export const _pool = Symbol ( 'pool' ) ;
14
- /** @internal private instance offset accessor */
15
- export const _offset = Symbol ( 'offset' ) ;
11
+ /**
12
+ * Retrieves a ObjectId pool and offset. This function may create a new ObjectId buffer pool and reset the pool offset
13
+ * @internal
14
+ */
15
+ function getPool ( ) : [ Uint8Array , number ] {
16
+ if ( ! currentPool || currentPoolOffset + 12 > currentPool . byteLength ) {
17
+ currentPool = ByteUtils . allocateUnsafe ( poolSize * 12 ) ;
18
+ currentPoolOffset = 0 ;
19
+ }
20
+ return [ currentPool , currentPoolOffset ] ;
21
+ }
16
22
17
23
/**
18
- * Create a new ObjectId buffer pool and reset the pool offset
24
+ * Increments the pool offset by 12 bytes
19
25
* @internal
20
26
*/
21
- function createPool ( ) : void {
22
- pool = ByteUtils . allocateUnsafe ( ObjectId . poolSize * 12 ) ;
23
- poolOffset = 0 ;
27
+ function incrementPool ( ) : void {
28
+ currentPoolOffset += 12 ;
24
29
}
25
30
26
31
// Regular expression that checks for hex value
@@ -57,14 +62,24 @@ export class ObjectId extends BSONValue {
57
62
static cacheHexString : boolean ;
58
63
59
64
/**
60
- * The size of the buffer pool for ObjectId .
65
+ * The size of the current ObjectId buffer pool .
61
66
*/
62
- static poolSize : number = defaultPoolSize ;
67
+ static get poolSize ( ) : number {
68
+ return poolSize ;
69
+ }
70
+
71
+ static set poolSize ( size : number ) {
72
+ const iSize = Math . ceil ( size ) ; // Ensure new pool size is an integer
73
+ if ( iSize <= 0 ) {
74
+ throw new BSONError ( 'poolSize must be a positive integer greater than 0' ) ;
75
+ }
76
+ poolSize = iSize ;
77
+ }
63
78
64
79
/** ObjectId buffer pool pointer @internal */
65
- private [ _pool ] : Uint8Array ;
80
+ private pool : Uint8Array ;
66
81
/** Buffer pool offset @internal */
67
- private [ _offset ] : number ;
82
+ private offset : number ;
68
83
69
84
/** ObjectId hexString cache @internal */
70
85
private __id ?: string ;
@@ -99,6 +114,13 @@ export class ObjectId extends BSONValue {
99
114
*
100
115
* @param inputId - A 12 byte binary Buffer.
101
116
*/
117
+ constructor ( inputId : Uint8Array ) ;
118
+ /**
119
+ * Create ObjectId from a large binary Buffer. Only 12 bytes starting from the offset are used.
120
+ * @internal
121
+ * @param inputId - A 12 byte binary Buffer.
122
+ * @param inputIndex - The offset to start reading the inputId buffer.
123
+ */
102
124
constructor ( inputId : Uint8Array , inputIndex ?: number ) ;
103
125
/** To generate a new ObjectId, use ObjectId() with no argument. */
104
126
constructor ( ) ;
@@ -133,23 +155,13 @@ export class ObjectId extends BSONValue {
133
155
workingId = inputId ;
134
156
}
135
157
136
- // If we have reached the end of the pool then create a new pool
137
- if ( ! pool || poolOffset + 12 > pool . byteLength ) {
138
- createPool ( ) ;
139
- }
140
- this [ _pool ] = pool ;
141
- this [ _offset ] = poolOffset ;
142
- poolOffset += 12 ;
158
+ const [ pool , offset ] = getPool ( ) ;
143
159
144
160
// The following cases use workingId to construct an ObjectId
145
161
if ( workingId == null || typeof workingId === 'number' ) {
146
162
// The most common use case (blank id, new objectId instance)
147
163
// Generate a new id
148
- ObjectId . generate (
149
- typeof workingId === 'number' ? workingId : undefined ,
150
- this [ _pool ] ,
151
- this [ _offset ]
152
- ) ;
164
+ ObjectId . generate ( typeof workingId === 'number' ? workingId : undefined , pool , offset ) ;
153
165
} else if ( ArrayBuffer . isView ( workingId ) ) {
154
166
if ( workingId . byteLength !== 12 && typeof inputIndex !== 'number' ) {
155
167
throw new BSONError ( 'Buffer length must be 12 or offset must be specified' ) ;
@@ -161,10 +173,10 @@ export class ObjectId extends BSONValue {
161
173
throw new BSONError ( 'Buffer offset must be a non-negative number less than buffer length' ) ;
162
174
}
163
175
inputIndex ??= 0 ;
164
- for ( let i = 0 ; i < 12 ; i ++ ) this [ _pool ] [ this [ _offset ] + i ] = workingId [ inputIndex + i ] ;
176
+ for ( let i = 0 ; i < 12 ; i ++ ) pool [ offset + i ] = workingId [ inputIndex + i ] ;
165
177
} else if ( typeof workingId === 'string' ) {
166
178
if ( workingId . length === 24 && checkForHexRegExp . test ( workingId ) ) {
167
- this [ _pool ] . set ( ByteUtils . fromHex ( workingId ) , this [ _offset ] ) ;
179
+ pool . set ( ByteUtils . fromHex ( workingId ) , offset ) ;
168
180
} else {
169
181
throw new BSONError (
170
182
'input must be a 24 character hex string, 12 byte Uint8Array, or an integer'
@@ -175,8 +187,12 @@ export class ObjectId extends BSONValue {
175
187
}
176
188
// If we are caching the hex string
177
189
if ( ObjectId . cacheHexString ) {
178
- this . __id = ByteUtils . toHex ( this [ _pool ] , this [ _offset ] , this [ _offset ] + 12 ) ;
190
+ this . __id = ByteUtils . toHex ( pool , offset , offset + 12 ) ;
179
191
}
192
+ // Increment pool offset once we have completed initialization
193
+ this . pool = pool ;
194
+ this . offset = offset ;
195
+ incrementPool ( ) ;
180
196
}
181
197
182
198
/** ObjectId bytes @internal */
@@ -189,14 +205,14 @@ export class ObjectId extends BSONValue {
189
205
* @readonly
190
206
*/
191
207
get id ( ) : Uint8Array {
192
- return this [ _pool ] . subarray ( this [ _offset ] , this [ _offset ] + 12 ) ;
208
+ return this . pool . subarray ( this . offset , this . offset + 12 ) ;
193
209
}
194
210
195
211
set id ( value : Uint8Array ) {
196
212
if ( value . byteLength !== 12 ) {
197
213
throw new BSONError ( 'input must be a 12 byte Uint8Array' ) ;
198
214
}
199
- this [ _pool ] . set ( value , this [ _offset ] ) ;
215
+ this . pool . set ( value , this . offset ) ;
200
216
if ( ObjectId . cacheHexString ) {
201
217
this . __id = ByteUtils . toHex ( value ) ;
202
218
}
@@ -208,7 +224,7 @@ export class ObjectId extends BSONValue {
208
224
return this . __id ;
209
225
}
210
226
211
- const hexString = ByteUtils . toHex ( this [ _pool ] , this [ _offset ] , this [ _offset ] + 12 ) ;
227
+ const hexString = ByteUtils . toHex ( this . pool , this . offset , this . offset + 12 ) ;
212
228
213
229
if ( ObjectId . cacheHexString && ! this . __id ) {
214
230
this . __id = hexString ;
@@ -302,9 +318,9 @@ export class ObjectId extends BSONValue {
302
318
}
303
319
304
320
if ( ObjectId . is ( otherId ) ) {
305
- if ( otherId [ _pool ] && typeof otherId [ _offset ] === 'number' ) {
321
+ if ( otherId . pool && typeof otherId . offset === 'number' ) {
306
322
for ( let i = 11 ; i >= 0 ; i -- ) {
307
- if ( this [ _pool ] [ this [ _offset ] + i ] !== otherId [ _pool ] [ otherId [ _offset ] + i ] ) {
323
+ if ( this . pool [ this . offset + i ] !== otherId . pool [ otherId . offset + i ] ) {
308
324
return false ;
309
325
}
310
326
}
@@ -330,7 +346,7 @@ export class ObjectId extends BSONValue {
330
346
/** Returns the generation date (accurate up to the second) that this ID was generated. */
331
347
getTimestamp ( ) : Date {
332
348
const timestamp = new Date ( ) ;
333
- const time = NumberUtils . getUint32BE ( this [ _pool ] , this [ _offset ] ) ;
349
+ const time = NumberUtils . getUint32BE ( this . pool , this . offset ) ;
334
350
timestamp . setTime ( Math . floor ( time ) * 1000 ) ;
335
351
return timestamp ;
336
352
}
@@ -342,18 +358,20 @@ export class ObjectId extends BSONValue {
342
358
343
359
/** @internal */
344
360
serializeInto ( uint8array : Uint8Array , index : number ) : 12 {
345
- uint8array [ index ] = this [ _pool ] [ this [ _offset ] ] ;
346
- uint8array [ index + 1 ] = this [ _pool ] [ this [ _offset ] + 1 ] ;
347
- uint8array [ index + 2 ] = this [ _pool ] [ this [ _offset ] + 2 ] ;
348
- uint8array [ index + 3 ] = this [ _pool ] [ this [ _offset ] + 3 ] ;
349
- uint8array [ index + 4 ] = this [ _pool ] [ this [ _offset ] + 4 ] ;
350
- uint8array [ index + 5 ] = this [ _pool ] [ this [ _offset ] + 5 ] ;
351
- uint8array [ index + 6 ] = this [ _pool ] [ this [ _offset ] + 6 ] ;
352
- uint8array [ index + 7 ] = this [ _pool ] [ this [ _offset ] + 7 ] ;
353
- uint8array [ index + 8 ] = this [ _pool ] [ this [ _offset ] + 8 ] ;
354
- uint8array [ index + 9 ] = this [ _pool ] [ this [ _offset ] + 9 ] ;
355
- uint8array [ index + 10 ] = this [ _pool ] [ this [ _offset ] + 10 ] ;
356
- uint8array [ index + 11 ] = this [ _pool ] [ this [ _offset ] + 11 ] ;
361
+ const pool = this . pool ;
362
+ const offset = this . offset ;
363
+ uint8array [ index ] = pool [ offset ] ;
364
+ uint8array [ index + 1 ] = pool [ offset + 1 ] ;
365
+ uint8array [ index + 2 ] = pool [ offset + 2 ] ;
366
+ uint8array [ index + 3 ] = pool [ offset + 3 ] ;
367
+ uint8array [ index + 4 ] = pool [ offset + 4 ] ;
368
+ uint8array [ index + 5 ] = pool [ offset + 5 ] ;
369
+ uint8array [ index + 6 ] = pool [ offset + 6 ] ;
370
+ uint8array [ index + 7 ] = pool [ offset + 7 ] ;
371
+ uint8array [ index + 8 ] = pool [ offset + 8 ] ;
372
+ uint8array [ index + 9 ] = pool [ offset + 9 ] ;
373
+ uint8array [ index + 10 ] = pool [ offset + 10 ] ;
374
+ uint8array [ index + 11 ] = pool [ offset + 11 ] ;
357
375
return 12 ;
358
376
}
359
377
0 commit comments