Skip to content

Commit d4a6f2c

Browse files
cjihrigtargos
authored andcommitted
fs: use async directory processing in cp()
The readdir() functions do not scale well, which is why opendir(), etc. were introduced. This is exacerbated in the current cp() implementation, which calls readdir() recursively. This commit updates cp() to use the opendir() style iteration. PR-URL: #41351 Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Tierney Cyren <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Juan José Arboleda <[email protected]> Reviewed-By: Mohammed Keyvanzadeh <[email protected]>
1 parent 1f6c4e8 commit d4a6f2c

File tree

2 files changed

+22
-14
lines changed

2 files changed

+22
-14
lines changed

lib/internal/fs/cp/cp-sync.js

+16-8
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ const {
3232
existsSync,
3333
lstatSync,
3434
mkdirSync,
35-
readdirSync,
35+
opendirSync,
3636
readlinkSync,
3737
statSync,
3838
symlinkSync,
@@ -275,14 +275,22 @@ function mkDirAndCopy(srcMode, src, dest, opts) {
275275
}
276276

277277
function copyDir(src, dest, opts) {
278-
readdirSync(src).forEach((item) => copyDirItem(item, src, dest, opts));
279-
}
278+
const dir = opendirSync(src);
279+
280+
try {
281+
let dirent;
280282

281-
function copyDirItem(item, src, dest, opts) {
282-
const srcItem = join(src, item);
283-
const destItem = join(dest, item);
284-
const { destStat } = checkPathsSync(srcItem, destItem, opts);
285-
return startCopy(destStat, srcItem, destItem, opts);
283+
while ((dirent = dir.readSync()) !== null) {
284+
const { name } = dirent;
285+
const srcItem = join(src, name);
286+
const destItem = join(dest, name);
287+
const { destStat } = checkPathsSync(srcItem, destItem, opts);
288+
289+
startCopy(destStat, srcItem, destItem, opts);
290+
}
291+
} finally {
292+
dir.closeSync();
293+
}
286294
}
287295

288296
function onLink(destStat, src, dest) {

lib/internal/fs/cp/cp.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ const {
4141
copyFile,
4242
lstat,
4343
mkdir,
44-
readdir,
44+
opendir,
4545
readlink,
4646
stat,
4747
symlink,
@@ -325,11 +325,11 @@ async function mkDirAndCopy(srcMode, src, dest, opts) {
325325
}
326326

327327
async function copyDir(src, dest, opts) {
328-
const dir = await readdir(src);
329-
for (let i = 0; i < dir.length; i++) {
330-
const item = dir[i];
331-
const srcItem = join(src, item);
332-
const destItem = join(dest, item);
328+
const dir = await opendir(src);
329+
330+
for await (const { name } of dir) {
331+
const srcItem = join(src, name);
332+
const destItem = join(dest, name);
333333
const { destStat } = await checkPaths(srcItem, destItem, opts);
334334
await startCopy(destStat, srcItem, destItem, opts);
335335
}

0 commit comments

Comments
 (0)