@@ -40,6 +40,7 @@ Section -> Buffer
40
40
41
41
// "wpc" + 1 in little-endian
42
42
const VERSION = 0x01637077 ;
43
+ const _1GiB = 1 * 1024 * 1024 * 1024 ;
43
44
44
45
/**
45
46
* @param {Buffer[] } buffers buffers
@@ -87,7 +88,7 @@ const readUInt64LE = Buffer.prototype.readBigUInt64LE
87
88
* @param {FileMiddleware } middleware this
88
89
* @param {BufferSerializableType[] | Promise<BufferSerializableType[]> } data data to be serialized
89
90
* @param {string | boolean } name file base name
90
- * @param {function(string | false, Buffer[]): Promise<void> } writeFile writes a file
91
+ * @param {function(string | false, Buffer[], number ): Promise<void> } writeFile writes a file
91
92
* @param {string | Hash } hashFunction hash function to use
92
93
* @returns {Promise<SerializeResult> } resulting file pointer and promise
93
94
*/
@@ -212,9 +213,9 @@ const serialize = async (
212
213
if ( name === true ) {
213
214
name = hashForName ( buf , hashFunction ) ;
214
215
}
215
- backgroundJobs . push ( writeFile ( name , buf ) ) ;
216
216
let size = 0 ;
217
217
for ( const b of buf ) size += b . length ;
218
+ backgroundJobs . push ( writeFile ( name , buf , size ) ) ;
218
219
return {
219
220
size,
220
221
name,
@@ -422,7 +423,7 @@ class FileMiddleware extends SerializerMiddleware {
422
423
// It's important that we don't touch existing files during serialization
423
424
// because serialize may read existing files (when deserializing)
424
425
const allWrittenFiles = new Set ( ) ;
425
- const writeFile = async ( name , content ) => {
426
+ const writeFile = async ( name , content , size ) => {
426
427
const file = name
427
428
? join ( this . fs , filename , `../${ name } ${ extension } ` )
428
429
: filename ;
@@ -441,10 +442,7 @@ class FileMiddleware extends SerializerMiddleware {
441
442
[ zConstants . BROTLI_PARAM_MODE ] : zConstants . BROTLI_MODE_TEXT ,
442
443
[ zConstants . BROTLI_PARAM_QUALITY ] : 2 ,
443
444
[ zConstants . BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING ] : true ,
444
- [ zConstants . BROTLI_PARAM_SIZE_HINT ] : content . reduce (
445
- ( size , b ) => size + b . length ,
446
- 0
447
- )
445
+ [ zConstants . BROTLI_PARAM_SIZE_HINT ] : size
448
446
}
449
447
} ) ;
450
448
}
@@ -456,8 +454,24 @@ class FileMiddleware extends SerializerMiddleware {
456
454
stream . on ( "error" , err => reject ( err ) ) ;
457
455
stream . on ( "finish" , ( ) => resolve ( ) ) ;
458
456
}
459
- for ( const b of content ) stream . write ( b ) ;
460
- stream . end ( ) ;
457
+ // use unsafe
458
+ if ( size <= _1GiB ) {
459
+ for ( const b of content ) stream . write ( b ) ;
460
+ return stream . end ( ) ;
461
+ }
462
+
463
+ const len = content . length ;
464
+ let i = 0 ;
465
+ const batchWrite = err => {
466
+ if ( i === len ) {
467
+ stream . end ( ) ;
468
+ return ;
469
+ }
470
+ // will be handle in "on" handler
471
+ if ( err ) return ;
472
+ stream . write ( content [ i ++ ] , batchWrite ) ;
473
+ } ;
474
+ batchWrite ( ) ;
461
475
} ) ;
462
476
if ( name ) allWrittenFiles . add ( file ) ;
463
477
} ;
0 commit comments