Skip to content

Commit c9d6520

Browse files
committed
unpack: conditionally use a file mapping to write files
Use a file mapping to write files up to 512KB. The limit where using a file mapping stops being an advantage varies from machine to machine. 512KB is a reasonable value to use here, close to the lower bound, to avoid tar becoming slower in some machines.
1 parent 9232b3d commit c9d6520

File tree

1 file changed

+10
-1
lines changed

1 file changed

+10
-1
lines changed

lib/unpack.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const assert = require('assert')
44
const EE = require('events').EventEmitter
55
const Parser = require('./parse.js')
66
const fs = require('fs')
7+
const { O_CREAT, O_TRUNC, O_WRONLY, UV_FS_O_FILEMAP = 0 } = fs.constants
78
const fsm = require('fs-minipass')
89
const path = require('path')
910
const mkdir = require('./mkdir.js')
@@ -79,6 +80,13 @@ const uint32 = (a, b, c) =>
7980
: b === b >>> 0 ? b
8081
: c
8182

83+
/* istanbul ignore next */
84+
const fMapEnabled = process.platform === 'win32' && !!UV_FS_O_FILEMAP
85+
const fMapLimit = 512 * 1024
86+
const fMapFlag = UV_FS_O_FILEMAP | O_TRUNC | O_CREAT | O_WRONLY
87+
/* istanbul ignore next */
88+
const getFlag = size => (fMapEnabled && size < fMapLimit) ? fMapFlag : 'w'
89+
8290
class Unpack extends Parser {
8391
constructor (opt) {
8492
if (!opt)
@@ -294,6 +302,7 @@ class Unpack extends Parser {
294302
[FILE] (entry) {
295303
const mode = entry.mode & 0o7777 || this.fmode
296304
const stream = new fsm.WriteStream(entry.absolute, {
305+
flags: getFlag(entry.size),
297306
mode: mode,
298307
autoClose: false
299308
})
@@ -515,7 +524,7 @@ class UnpackSync extends Unpack {
515524
let stream
516525
let fd
517526
try {
518-
fd = fs.openSync(entry.absolute, 'w', mode)
527+
fd = fs.openSync(entry.absolute, getFlag(entry.size), mode)
519528
} catch (er) {
520529
return oner(er)
521530
}

0 commit comments

Comments
 (0)