Skip to content

Commit

Permalink
realpath performance improvements (resolves #174)
Browse files Browse the repository at this point in the history
  • Loading branch information
james-pre committed Jan 20, 2025
1 parent 9a58b1a commit cf92b8b
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 0 deletions.
Empty file modified scripts/ci-cli.js
100644 → 100755
Empty file.
22 changes: 22 additions & 0 deletions src/vfs/promises.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1020,6 +1020,28 @@ export async function realpath(
path = normalizePath(path);
const ctx_path = (this?.root || '') + path;
if (cache.paths.hasAsync(ctx_path)) return cache.paths.getAsync(ctx_path)!;

/* Try to resolve it directly. If this works,
that means we don't need to perform any resolution for parent directories. */
try {
const { fs, path: resolvedPath } = resolveMount(path, this);
// Stat it to make sure it exists
const stats = await fs.stat(resolvedPath);

let real = path.toString();

if (stats.isSymbolicLink()) {
const target = resolve(dirname(resolvedPath), (await readlink.call(this, resolvedPath, options)).toString());
real = cache.paths.get((this?.root || '') + target) || (await realpath.call(this, target));
cache.paths.set(ctx_path, real);
}

cache.paths.set(path.toString(), real);
return real;
} catch {
// Go the long way
}

const { base, dir } = parse(path);
const realDir = dir == '/' ? '/' : await (cache.paths.getAsync((this?.root || '') + dir) || realpath.call(this, dir));
const lpath = join(realDir, base);
Expand Down
22 changes: 22 additions & 0 deletions src/vfs/sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,28 @@ export function realpathSync(this: V_Context, path: fs.PathLike, options?: fs.En
path = normalizePath(path);
const ctx_path = (this?.root || '') + path;
if (cache.paths.has(ctx_path)) return cache.paths.get(ctx_path)!;

/* Try to resolve it directly. If this works,
that means we don't need to perform any resolution for parent directories. */
try {
const { fs, path: resolvedPath } = resolveMount(path, this);
// Stat it to make sure it exists
const stats = fs.statSync(resolvedPath);

let real = path;

if (stats.isSymbolicLink()) {
const target = resolve(dirname(resolvedPath), readlinkSync.call(this, resolvedPath, options).toString());
real = cache.paths.get((this?.root || '') + target) || realpathSync.call(this, target);
cache.paths.set(ctx_path, real);
}

cache.paths.set(path, real);
return real;
} catch {
// Go the long way
}

const { base, dir } = parse(path);
const realDir = dir == '/' ? '/' : cache.paths.get((this?.root || '') + dir) || realpathSync.call(this, dir);
const lpath = join(realDir, base);
Expand Down

0 comments on commit cf92b8b

Please sign in to comment.