Skip to content

Commit

Permalink
fs: more realpath*() optimizations
Browse files Browse the repository at this point in the history
Including:

* Avoid regexp on non-Windows platforms when parsing the root of a path

Backport-PR-URL: nodejs#11665
  • Loading branch information
JLHwung committed Nov 1, 2017
1 parent b82c613 commit 89048c2
Showing 1 changed file with 34 additions and 30 deletions.
64 changes: 34 additions & 30 deletions lib/fs.js
Expand Up @@ -1622,10 +1622,23 @@ fs.unwatchFile = function(filename, listener) {
};


// Regex to find the device root, including trailing slash. E.g. 'c:\\'.
const splitRootRe = isWindows ?
/^(?:[a-zA-Z]:|[\\/]{2}[^\\/]+[\\/][^\\/]+)?[\\/]*/ :
/^[/]*/;
var splitRoot;
if (isWindows) {
// Regex to find the device root on Windows (e.g. 'c:\\'), including trailing
// slash.
const splitRootRe = /^(?:[a-zA-Z]:|[\\/]{2}[^\\/]+[\\/][^\\/]+)?[\\/]*/;
splitRoot = function splitRoot(str) {
return splitRootRe.exec(str)[0];
};
} else {
splitRoot = function splitRoot(str) {
for (var i = 0; i < str.length; ++i) {
if (str.charCodeAt(i) !== 47/*'/'*/)
return str.slice(0, i);
}
return str;
};
}

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

// Skip over roots
var m = splitRootRe.exec(p);
pos = m[0].length;
current = m[0];
base = m[0];
// Skip over roots
current = base = splitRoot(p);
pos = current.length;

// On windows, check that the root exists. On unix there is no need.
if (isWindows && !knownHard[base]) {
// On windows, check that the root exists. On unix there is no need.
if (isWindows && !knownHard[base]) {
binding.lstat(pathModule._makeLong(base));
knownHard[base] = true;
}
knownHard[base] = true;
}

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

binding.lstat(pathModule._makeLong(base));
var baseLong = pathModule._makeLong(base);
binding.lstat(baseLong);

if ((statValues[1/*mode*/] & S_IFMT) !== S_IFLNK) {
knownHard[base] = true;
Expand All @@ -1752,8 +1764,8 @@ fs.realpathSync = function realpathSync(p, options) {
}
}
if (linkTarget === null) {
binding.stat(pathModule._makeLong(base));
linkTarget = binding.readlink(pathModule._makeLong(base));
binding.stat(baseLong);
linkTarget = binding.readlink(baseLong);
}
resolvedLink = pathModule.resolve(previous, linkTarget);

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

// Skip over roots
m = splitRootRe.exec(p);
pos = m[0].length;
current = m[0];
base = m[0];
current = base = splitRoot(p);
pos = current.length;

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

var m = splitRootRe.exec(p);
pos = m[0].length;
current = m[0];
base = m[0];
previous = '';
current = base = splitRoot(p);
pos = current.length;

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

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

0 comments on commit 89048c2

Please sign in to comment.