@@ -4,23 +4,28 @@ import { type InspectFn, defaultInspect } from './parser/utils';
44import { ByteUtils } from './utils/byte_utils' ;
55import { NumberUtils } from './utils/number_utils' ;
66
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 ;
1010
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+ }
1622
1723/**
18- * Create a new ObjectId buffer pool and reset the pool offset
24+ * Increments the pool offset by 12 bytes
1925 * @internal
2026 */
21- function createPool ( ) : void {
22- pool = ByteUtils . allocateUnsafe ( ObjectId . poolSize * 12 ) ;
23- poolOffset = 0 ;
27+ function incrementPool ( ) : void {
28+ currentPoolOffset += 12 ;
2429}
2530
2631// Regular expression that checks for hex value
@@ -57,14 +62,24 @@ export class ObjectId extends BSONValue {
5762 static cacheHexString : boolean ;
5863
5964 /**
60- * The size of the buffer pool for ObjectId .
65+ * The size of the current ObjectId buffer pool .
6166 */
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+ }
6378
6479 /** ObjectId buffer pool pointer @internal */
65- private [ _pool ] : Uint8Array ;
80+ private pool : Uint8Array ;
6681 /** Buffer pool offset @internal */
67- private [ _offset ] : number ;
82+ private offset : number ;
6883
6984 /** ObjectId hexString cache @internal */
7085 private __id ?: string ;
@@ -99,6 +114,13 @@ export class ObjectId extends BSONValue {
99114 *
100115 * @param inputId - A 12 byte binary Buffer.
101116 */
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+ */
102124 constructor ( inputId : Uint8Array , inputIndex ?: number ) ;
103125 /** To generate a new ObjectId, use ObjectId() with no argument. */
104126 constructor ( ) ;
@@ -133,23 +155,13 @@ export class ObjectId extends BSONValue {
133155 workingId = inputId ;
134156 }
135157
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 ( ) ;
143159
144160 // The following cases use workingId to construct an ObjectId
145161 if ( workingId == null || typeof workingId === 'number' ) {
146162 // The most common use case (blank id, new objectId instance)
147163 // 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 ) ;
153165 } else if ( ArrayBuffer . isView ( workingId ) ) {
154166 if ( workingId . byteLength !== 12 && typeof inputIndex !== 'number' ) {
155167 throw new BSONError ( 'Buffer length must be 12 or offset must be specified' ) ;
@@ -161,10 +173,10 @@ export class ObjectId extends BSONValue {
161173 throw new BSONError ( 'Buffer offset must be a non-negative number less than buffer length' ) ;
162174 }
163175 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 ] ;
165177 } else if ( typeof workingId === 'string' ) {
166178 if ( workingId . length === 24 && checkForHexRegExp . test ( workingId ) ) {
167- this [ _pool ] . set ( ByteUtils . fromHex ( workingId ) , this [ _offset ] ) ;
179+ pool . set ( ByteUtils . fromHex ( workingId ) , offset ) ;
168180 } else {
169181 throw new BSONError (
170182 'input must be a 24 character hex string, 12 byte Uint8Array, or an integer'
@@ -175,8 +187,12 @@ export class ObjectId extends BSONValue {
175187 }
176188 // If we are caching the hex string
177189 if ( ObjectId . cacheHexString ) {
178- this . __id = ByteUtils . toHex ( this [ _pool ] , this [ _offset ] , this [ _offset ] + 12 ) ;
190+ this . __id = ByteUtils . toHex ( pool , offset , offset + 12 ) ;
179191 }
192+ // Increment pool offset once we have completed initialization
193+ this . pool = pool ;
194+ this . offset = offset ;
195+ incrementPool ( ) ;
180196 }
181197
182198 /** ObjectId bytes @internal */
@@ -189,14 +205,14 @@ export class ObjectId extends BSONValue {
189205 * @readonly
190206 */
191207 get id ( ) : Uint8Array {
192- return this [ _pool ] . subarray ( this [ _offset ] , this [ _offset ] + 12 ) ;
208+ return this . pool . subarray ( this . offset , this . offset + 12 ) ;
193209 }
194210
195211 set id ( value : Uint8Array ) {
196212 if ( value . byteLength !== 12 ) {
197213 throw new BSONError ( 'input must be a 12 byte Uint8Array' ) ;
198214 }
199- this [ _pool ] . set ( value , this [ _offset ] ) ;
215+ this . pool . set ( value , this . offset ) ;
200216 if ( ObjectId . cacheHexString ) {
201217 this . __id = ByteUtils . toHex ( value ) ;
202218 }
@@ -208,7 +224,7 @@ export class ObjectId extends BSONValue {
208224 return this . __id ;
209225 }
210226
211- const hexString = ByteUtils . toHex ( this [ _pool ] , this [ _offset ] , this [ _offset ] + 12 ) ;
227+ const hexString = ByteUtils . toHex ( this . pool , this . offset , this . offset + 12 ) ;
212228
213229 if ( ObjectId . cacheHexString && ! this . __id ) {
214230 this . __id = hexString ;
@@ -302,9 +318,9 @@ export class ObjectId extends BSONValue {
302318 }
303319
304320 if ( ObjectId . is ( otherId ) ) {
305- if ( otherId [ _pool ] && typeof otherId [ _offset ] === 'number' ) {
321+ if ( otherId . pool && typeof otherId . offset === 'number' ) {
306322 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 ] ) {
308324 return false ;
309325 }
310326 }
@@ -330,7 +346,7 @@ export class ObjectId extends BSONValue {
330346 /** Returns the generation date (accurate up to the second) that this ID was generated. */
331347 getTimestamp ( ) : Date {
332348 const timestamp = new Date ( ) ;
333- const time = NumberUtils . getUint32BE ( this [ _pool ] , this [ _offset ] ) ;
349+ const time = NumberUtils . getUint32BE ( this . pool , this . offset ) ;
334350 timestamp . setTime ( Math . floor ( time ) * 1000 ) ;
335351 return timestamp ;
336352 }
@@ -342,18 +358,20 @@ export class ObjectId extends BSONValue {
342358
343359 /** @internal */
344360 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 ] ;
357375 return 12 ;
358376 }
359377
0 commit comments