Skip to content

Commit 97f813a

Browse files
committed
Extract getFlag fmap detection to a tested module
1 parent 150da0e commit 97f813a

3 files changed

Lines changed: 68 additions & 8 deletions

File tree

lib/get-write-flag.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Get the appropriate flag to use for creating files
2+
// We use fmap on Windows platforms for files less than
3+
// 512kb. This is a fairly low limit, but avoids making
4+
// things slower in some cases. Since most of what this
5+
// library is used for is extracting tarballs of many
6+
// relatively small files in npm packages and the like,
7+
// it can be a big boost on Windows platforms.
8+
// Only supported in Node v12.9.0 and above.
9+
const platform = process.env.__FAKE_PLATFORM__ || process.platform
10+
const isWindows = platform === 'win32'
11+
const fs = require('fs')
12+
const { O_CREAT, O_TRUNC, O_WRONLY, UV_FS_O_FILEMAP = 0 } = fs.constants
13+
const fMapEnabled = isWindows && !!UV_FS_O_FILEMAP
14+
const fMapLimit = 512 * 1024
15+
const fMapFlag = UV_FS_O_FILEMAP | O_TRUNC | O_CREAT | O_WRONLY
16+
module.exports = size => (fMapEnabled && size < fMapLimit) ? fMapFlag : 'w'

lib/unpack.js

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ const assert = require('assert')
1010
const EE = require('events').EventEmitter
1111
const Parser = require('./parse.js')
1212
const fs = require('fs')
13-
const { O_CREAT, O_TRUNC, O_WRONLY, UV_FS_O_FILEMAP = 0 } = fs.constants
1413
const fsm = require('fs-minipass')
1514
const path = require('path')
1615
const mkdir = require('./mkdir.js')
@@ -43,6 +42,7 @@ const DOCHOWN = Symbol('doChown')
4342
const UID = Symbol('uid')
4443
const GID = Symbol('gid')
4544
const crypto = require('crypto')
45+
const getFlag = require('./get-write-flag.js')
4646

4747
/* istanbul ignore next */
4848
const neverCalled = () => {
@@ -93,13 +93,6 @@ const uint32 = (a, b, c) =>
9393
: b === b >>> 0 ? b
9494
: c
9595

96-
/* istanbul ignore next */
97-
const fMapEnabled = process.platform === 'win32' && !!UV_FS_O_FILEMAP
98-
const fMapLimit = 512 * 1024
99-
const fMapFlag = UV_FS_O_FILEMAP | O_TRUNC | O_CREAT | O_WRONLY
100-
/* istanbul ignore next */
101-
const getFlag = size => (fMapEnabled && size < fMapLimit) ? fMapFlag : 'w'
102-
10396
class Unpack extends Parser {
10497
constructor (opt) {
10598
if (!opt)

test/get-write-flag.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
const t = require('tap')
2+
3+
// run three scenarios
4+
// unix (no fmap)
5+
// win32 (without fmap support)
6+
// win32 (with fmap support)
7+
8+
const fs = require('fs')
9+
const hasFmap = !!fs.constants.UV_FS_O_FILEMAP
10+
const platform = process.platform
11+
12+
switch (process.argv[2]) {
13+
case 'win32-fmap': {
14+
if (!hasFmap)
15+
fs.constants.UV_FS_O_FILEMAP = 0x20000000
16+
const { O_CREAT, O_TRUNC, O_WRONLY, UV_FS_O_FILEMAP } = fs.constants
17+
if (platform !== 'win32')
18+
process.env.__FAKE_PLATFORM__ = 'win32'
19+
const getFlag = require('../lib/get-write-flag.js')
20+
t.equal(getFlag(1), UV_FS_O_FILEMAP | O_TRUNC | O_CREAT | O_WRONLY)
21+
t.equal(getFlag(512 * 1024 + 1), 'w')
22+
break
23+
}
24+
25+
case 'win32-nofmap': {
26+
if (hasFmap)
27+
fs.constants.UV_FS_O_FILEMAP = 0
28+
if (platform !== 'win32')
29+
process.env.__FAKE_PLATFORM__ = 'win32'
30+
const getFlag = require('../lib/get-write-flag.js')
31+
t.equal(getFlag(1), 'w')
32+
t.equal(getFlag(512 * 1024 + 1), 'w')
33+
break
34+
}
35+
36+
case 'unix': {
37+
if (platform === 'win32')
38+
process.env.__FAKE_PLATFORM__ = 'darwin'
39+
const getFlag = require('../lib/get-write-flag.js')
40+
t.equal(getFlag(1), 'w')
41+
t.equal(getFlag(512 * 1024 + 1), 'w')
42+
break
43+
}
44+
45+
default: {
46+
const node = process.execPath
47+
t.spawn(node, [__filename, 'win32-fmap'])
48+
t.spawn(node, [__filename, 'win32-nofmap'])
49+
t.spawn(node, [__filename, 'unix'])
50+
}
51+
}

0 commit comments

Comments
 (0)