Skip to content

Commit 89048c2

Browse files
committed
fs: more realpath*() optimizations
Including: * Avoid regexp on non-Windows platforms when parsing the root of a path Backport-PR-URL: nodejs#11665
1 parent b82c613 commit 89048c2

1 file changed

Lines changed: 34 additions & 30 deletions

File tree

lib/fs.js

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1622,10 +1622,23 @@ fs.unwatchFile = function(filename, listener) {
16221622
};
16231623

16241624

1625-
// Regex to find the device root, including trailing slash. E.g. 'c:\\'.
1626-
const splitRootRe = isWindows ?
1627-
/^(?:[a-zA-Z]:|[\\/]{2}[^\\/]+[\\/][^\\/]+)?[\\/]*/ :
1628-
/^[/]*/;
1625+
var splitRoot;
1626+
if (isWindows) {
1627+
// Regex to find the device root on Windows (e.g. 'c:\\'), including trailing
1628+
// slash.
1629+
const splitRootRe = /^(?:[a-zA-Z]:|[\\/]{2}[^\\/]+[\\/][^\\/]+)?[\\/]*/;
1630+
splitRoot = function splitRoot(str) {
1631+
return splitRootRe.exec(str)[0];
1632+
};
1633+
} else {
1634+
splitRoot = function splitRoot(str) {
1635+
for (var i = 0; i < str.length; ++i) {
1636+
if (str.charCodeAt(i) !== 47/*'/'*/)
1637+
return str.slice(0, i);
1638+
}
1639+
return str;
1640+
};
1641+
}
16291642

16301643
function encodeRealpathResult(result, options, err) {
16311644
if (!options || !options.encoding || options.encoding === 'utf8' || err)
@@ -1688,17 +1701,15 @@ fs.realpathSync = function realpathSync(p, options) {
16881701
// the partial path scanned in the previous round, with slash
16891702
var previous;
16901703

1691-
// Skip over roots
1692-
var m = splitRootRe.exec(p);
1693-
pos = m[0].length;
1694-
current = m[0];
1695-
base = m[0];
1704+
// Skip over roots
1705+
current = base = splitRoot(p);
1706+
pos = current.length;
16961707

1697-
// On windows, check that the root exists. On unix there is no need.
1698-
if (isWindows && !knownHard[base]) {
1708+
// On windows, check that the root exists. On unix there is no need.
1709+
if (isWindows && !knownHard[base]) {
16991710
binding.lstat(pathModule._makeLong(base));
1700-
knownHard[base] = true;
1701-
}
1711+
knownHard[base] = true;
1712+
}
17021713

17031714
// walk down the path, swapping out linked path parts for their real
17041715
// values
@@ -1731,7 +1742,8 @@ fs.realpathSync = function realpathSync(p, options) {
17311742
// Use stats array directly to avoid creating an fs.Stats instance just
17321743
// for our internal use.
17331744

1734-
binding.lstat(pathModule._makeLong(base));
1745+
var baseLong = pathModule._makeLong(base);
1746+
binding.lstat(baseLong);
17351747

17361748
if ((statValues[1/*mode*/] & S_IFMT) !== S_IFLNK) {
17371749
knownHard[base] = true;
@@ -1752,8 +1764,8 @@ fs.realpathSync = function realpathSync(p, options) {
17521764
}
17531765
}
17541766
if (linkTarget === null) {
1755-
binding.stat(pathModule._makeLong(base));
1756-
linkTarget = binding.readlink(pathModule._makeLong(base));
1767+
binding.stat(baseLong);
1768+
linkTarget = binding.readlink(baseLong);
17571769
}
17581770
resolvedLink = pathModule.resolve(previous, linkTarget);
17591771

@@ -1765,10 +1777,8 @@ fs.realpathSync = function realpathSync(p, options) {
17651777
p = pathModule.resolve(resolvedLink, p.slice(pos));
17661778

17671779
// Skip over roots
1768-
m = splitRootRe.exec(p);
1769-
pos = m[0].length;
1770-
current = m[0];
1771-
base = m[0];
1780+
current = base = splitRoot(p);
1781+
pos = current.length;
17721782

17731783
// On windows, check that the root exists. On unix there is no need.
17741784
if (isWindows && !knownHard[base]) {
@@ -1815,11 +1825,8 @@ fs.realpath = function realpath(p, options, callback) {
18151825
// the partial path scanned in the previous round, with slash
18161826
var previous;
18171827

1818-
var m = splitRootRe.exec(p);
1819-
pos = m[0].length;
1820-
current = m[0];
1821-
base = m[0];
1822-
previous = '';
1828+
current = base = splitRoot(p);
1829+
pos = current.length;
18231830

18241831
// On windows, check that the root exists. On unix there is no need.
18251832
if (isWindows && !knownHard[base]) {
@@ -1906,11 +1913,8 @@ fs.realpath = function realpath(p, options, callback) {
19061913
function gotResolvedLink(resolvedLink) {
19071914
// resolve the link, then start over
19081915
p = pathModule.resolve(resolvedLink, p.slice(pos));
1909-
var m = splitRootRe.exec(p);
1910-
pos = m[0].length;
1911-
current = m[0];
1912-
base = m[0];
1913-
previous = '';
1916+
current = base = splitRoot(p);
1917+
pos = current.length;
19141918

19151919
// On windows, check that the root exists. On unix there is no need.
19161920
if (isWindows && !knownHard[base]) {

0 commit comments

Comments
 (0)