fs: improve error performance of readdirSync

PR-URL: https://github.com/nodejs/node/pull/50131
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
This commit is contained in:
Yagiz Nizipli authored and GitHub committed 2023-10-14 19:35:01 +00:00
1 parent 9df864ddeb
commit 18a818744f
5 files changed
+28 -35

No files matched your search

+11 -11
View File
@@ -1410,17 +1410,16 @@ function readdirSyncRecursive(basePath, options) {
const readdirResults = [];
const pathsQueue = [basePath];
const ctx = { path: basePath };
function read(path) {
ctx.path = path;
const readdirResult = binding.readdir(
pathModule.toNamespacedPath(path),
encoding,
withFileTypes,
undefined,
ctx,
);
handleErrorFromBinding(ctx);
if (readdirResult === undefined) {
return;
}
if (withFileTypes) {
// Calling `readdir` with `withFileTypes=true`, the result is an array of arrays.
@@ -1519,12 +1518,13 @@ function readdirSync(path, options) {
return readdirSyncRecursive(path, options);
}
const ctx = { path };
const result = binding.readdir(pathModule.toNamespacedPath(path),
options.encoding, !!options.withFileTypes,
undefined, ctx);
handleErrorFromBinding(ctx);
return options.withFileTypes ? getDirents(path, result) : result;
const result = binding.readdir(
pathModule.toNamespacedPath(path),
options.encoding,
!!options.withFileTypes,
);
return result !== undefined && options.withFileTypes ? getDirents(path, result) : result;
}
/**
+11 -18
View File
@@ -1891,8 +1891,8 @@ static void ReadDir(const FunctionCallbackInfo<Value>& args) {
bool with_types = args[2]->IsTrue();
FSReqBase* req_wrap_async = GetReqWrap(args, 3);
if (req_wrap_async != nullptr) { // readdir(path, encoding, withTypes, req)
if (argc > 3) { // readdir(path, encoding, withTypes, req)
FSReqBase* req_wrap_async = GetReqWrap(args, 3);
req_wrap_async->set_with_file_types(with_types);
FS_ASYNC_TRACE_BEGIN1(
UV_FS_SCANDIR, req_wrap_async, "path", TRACE_STR_COPY(*path))
@@ -1905,18 +1905,16 @@ static void ReadDir(const FunctionCallbackInfo<Value>& args) {
uv_fs_scandir,
*path,
0 /*flags*/);
} else { // readdir(path, encoding, withTypes, undefined, ctx)
CHECK_EQ(argc, 5);
FSReqWrapSync req_wrap_sync;
} else { // readdir(path, encoding, withTypes)
FSReqWrapSync req_wrap_sync("scandir", *path);
FS_SYNC_TRACE_BEGIN(readdir);
int err = SyncCall(env, args[4], &req_wrap_sync, "scandir",
uv_fs_scandir, *path, 0 /*flags*/);
int err = SyncCallAndThrowOnError(
env, &req_wrap_sync, uv_fs_scandir, *path, 0 /*flags*/);
FS_SYNC_TRACE_END(readdir);
if (err < 0) {
return; // syscall failed, no need to continue, error info is in ctx
if (is_uv_error(err)) {
return;
}
CHECK_GE(req_wrap_sync.req.result, 0);
int r;
std::vector<Local<Value>> name_v;
std::vector<Local<Value>> type_v;
@@ -1927,12 +1925,8 @@ static void ReadDir(const FunctionCallbackInfo<Value>& args) {
r = uv_fs_scandir_next(&(req_wrap_sync.req), &ent);
if (r == UV_EOF)
break;
if (r != 0) {
Local<Object> ctx = args[4].As<Object>();
ctx->Set(env->context(), env->errno_string(),
Integer::New(isolate, r)).Check();
ctx->Set(env->context(), env->syscall_string(),
OneByteString(isolate, "readdir")).Check();
if (is_uv_error(r)) {
env->ThrowUVException(r, "scandir", nullptr, *path);
return;
}
@@ -1943,8 +1937,7 @@ static void ReadDir(const FunctionCallbackInfo<Value>& args) {
&error);
if (filename.IsEmpty()) {
Local<Object> ctx = args[4].As<Object>();
ctx->Set(env->context(), env->error_string(), error).Check();
isolate->ThrowException(error);
return;
}
+2 -2
View File
@@ -29,7 +29,7 @@ tmpdir.refresh();
// Create the necessary files
files.forEach(function(currentFile) {
fs.closeSync(fs.openSync(`${readdirDir}/${currentFile}`, 'w'));
fs.writeFileSync(`${readdirDir}/${currentFile}`, '', 'utf8');
});
@@ -95,7 +95,7 @@ binding.readdir = common.mustCall((path, encoding, types, req, ctx) => {
};
oldReaddir(path, encoding, types, req);
} else {
const results = oldReaddir(path, encoding, types, req, ctx);
const results = oldReaddir(path, encoding, types);
results[1] = results[1].map(() => UNKNOWN);
return results;
}
+2 -2
View File
@@ -180,9 +180,9 @@ function testError() {
/^Uncaught Error: ENOENT: no such file or directory, scandir '.*nonexistent\?'/,
/Object\.readdirSync/,
/^ {2}errno: -(2|4058),$/,
" syscall: 'scandir',",
" code: 'ENOENT',",
" path: '/nonexistent?'",
" syscall: 'scandir',",
/^ {2}path: '*'/,
'}',
"'ENOENT'",
"'scandir'",
+2 -2
View File
@@ -166,8 +166,8 @@ declare namespace InternalFSBinding {
function readdir(path: StringOrBuffer, encoding: unknown, withFileTypes: true, req: FSReqCallback<[string[], number[]]>): void;
function readdir(path: StringOrBuffer, encoding: unknown, withFileTypes: false, req: FSReqCallback<string[]>): void;
function readdir(path: StringOrBuffer, encoding: unknown, withFileTypes: boolean, req: undefined, ctx: FSSyncContext): string[] | [string[], number[]];
function readdir(path: StringOrBuffer, encoding: unknown, withFileTypes: true, req: undefined, ctx: FSSyncContext): [string[], number[]];
function readdir(path: StringOrBuffer, encoding: unknown, withFileTypes: false, req: undefined, ctx: FSSyncContext): string[];
function readdir(path: StringOrBuffer, encoding: unknown, withFileTypes: true): [string[], number[]];
function readdir(path: StringOrBuffer, encoding: unknown, withFileTypes: false): string[];
function readdir(path: StringOrBuffer, encoding: unknown, withFileTypes: boolean, usePromises: typeof kUsePromises): Promise<string[] | [string[], number[]]>;
function readdir(path: StringOrBuffer, encoding: unknown, withFileTypes: true, usePromises: typeof kUsePromises): Promise<[string[], number[]]>;
function readdir(path: StringOrBuffer, encoding: unknown, withFileTypes: false, usePromises: typeof kUsePromises): Promise<string[]>;