Skip to content

Commit

Permalink
fs: replace traverse with readdir for performance
Browse files Browse the repository at this point in the history
  • Loading branch information
anonrig committed Oct 21, 2022
1 parent 9316792 commit fd0a954
Showing 1 changed file with 13 additions and 27 deletions.
40 changes: 13 additions & 27 deletions lib/internal/fs/linux_watcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const { SafeMap, Symbol, StringPrototypeStartsWith } = primordials;
const { validateObject } = require('internal/validators');
const { kEmptyObject } = require('internal/util');
const { ERR_FEATURE_UNAVAILABLE_ON_PLATFORM } = require('internal/errors');
const { Dirent, UV_DIRENT_DIR } = require('internal/fs/utils');

const kFSWatchStart = Symbol('kFSWatchStart');

Expand All @@ -22,35 +23,20 @@ function lazyLoadFsSync() {
return internalSync;
}

async function traverse(dir, files = new SafeMap()) {
const { stat, opendir } = lazyLoadFsPromises();
function traverse(dir, files = new SafeMap()) {
const { readdirSync } = lazyLoadFsSync()

files.set(dir, await stat(dir));
const filenames = readdirSync(dir, { withFileTypes: true });

try {
const directory = await opendir(dir);
files.set(dir, new Dirent(dir, UV_DIRENT_DIR));

for await (const file of directory) {
const f = path.join(dir, file.name);
for (let file of filenames) {
const f = path.join(dir, file.name);

try {
const stats = await stat(f);
files.set(f, file);

files.set(f, stats);

if (stats.isDirectory()) {
await traverse(f, files);
}
} catch (error) {
if (error.code !== 'ENOENT' || error.code !== 'EPERM') {
this.emit('error', error);
}
}

}
} catch (error) {
if (error.code !== 'EACCES') {
this.emit('error', error);
if (file.isDirectory()) {
traverse(f, files);
}
}

Expand Down Expand Up @@ -154,7 +140,7 @@ class FSWatcher extends EventEmitter {
persistent: this.#options.persistent,
}, (statWatcher, previousStatWatcher) => {
if (existingStat && !existingStat.isDirectory() &&
statWatcher.nlink !== 0 && existingStat.mtime.getTime() === statWatcher.mtime.getTime()) {
statWatcher.nlink !== 0 && existingStat.mtime?.getTime() === statWatcher.mtime?.getTime()) {
return;
}

Expand All @@ -180,10 +166,10 @@ class FSWatcher extends EventEmitter {
/**
* @param {string | Buffer | URL} filename
*/
async [kFSWatchStart](filename) {
[kFSWatchStart](filename) {
this.#rootPath = filename;
this.#closed = false;
this.#files = await traverse(filename);
this.#files = traverse(filename);

for (const f of this.#files.keys()) {
this.#watchFile(f);
Expand Down

0 comments on commit fd0a954

Please sign in to comment.