Skip to content

Commit fd0a954

Browse files
committed
fs: replace traverse with readdir for performance
1 parent 9316792 commit fd0a954

File tree

1 file changed

+13
-27
lines changed

1 file changed

+13
-27
lines changed

lib/internal/fs/linux_watcher.js

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const { SafeMap, Symbol, StringPrototypeStartsWith } = primordials;
66
const { validateObject } = require('internal/validators');
77
const { kEmptyObject } = require('internal/util');
88
const { ERR_FEATURE_UNAVAILABLE_ON_PLATFORM } = require('internal/errors');
9+
const { Dirent, UV_DIRENT_DIR } = require('internal/fs/utils');
910

1011
const kFSWatchStart = Symbol('kFSWatchStart');
1112

@@ -22,35 +23,20 @@ function lazyLoadFsSync() {
2223
return internalSync;
2324
}
2425

25-
async function traverse(dir, files = new SafeMap()) {
26-
const { stat, opendir } = lazyLoadFsPromises();
26+
function traverse(dir, files = new SafeMap()) {
27+
const { readdirSync } = lazyLoadFsSync()
2728

28-
files.set(dir, await stat(dir));
29+
const filenames = readdirSync(dir, { withFileTypes: true });
2930

30-
try {
31-
const directory = await opendir(dir);
31+
files.set(dir, new Dirent(dir, UV_DIRENT_DIR));
3232

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

36-
try {
37-
const stats = await stat(f);
36+
files.set(f, file);
3837

39-
files.set(f, stats);
40-
41-
if (stats.isDirectory()) {
42-
await traverse(f, files);
43-
}
44-
} catch (error) {
45-
if (error.code !== 'ENOENT' || error.code !== 'EPERM') {
46-
this.emit('error', error);
47-
}
48-
}
49-
50-
}
51-
} catch (error) {
52-
if (error.code !== 'EACCES') {
53-
this.emit('error', error);
38+
if (file.isDirectory()) {
39+
traverse(f, files);
5440
}
5541
}
5642

@@ -154,7 +140,7 @@ class FSWatcher extends EventEmitter {
154140
persistent: this.#options.persistent,
155141
}, (statWatcher, previousStatWatcher) => {
156142
if (existingStat && !existingStat.isDirectory() &&
157-
statWatcher.nlink !== 0 && existingStat.mtime.getTime() === statWatcher.mtime.getTime()) {
143+
statWatcher.nlink !== 0 && existingStat.mtime?.getTime() === statWatcher.mtime?.getTime()) {
158144
return;
159145
}
160146

@@ -180,10 +166,10 @@ class FSWatcher extends EventEmitter {
180166
/**
181167
* @param {string | Buffer | URL} filename
182168
*/
183-
async [kFSWatchStart](filename) {
169+
[kFSWatchStart](filename) {
184170
this.#rootPath = filename;
185171
this.#closed = false;
186-
this.#files = await traverse(filename);
172+
this.#files = traverse(filename);
187173

188174
for (const f of this.#files.keys()) {
189175
this.#watchFile(f);

0 commit comments

Comments
 (0)