Skip to content

Commit b618fe2

Browse files
anonrigruyadorno
authored andcommitted
fs: improve error performance of opendirSync
PR-URL: #49705 Refs: nodejs/performance#106 Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
1 parent bbc7105 commit b618fe2

3 files changed

Lines changed: 73 additions & 9 deletions

File tree

‎benchmark/fs/bench-opendirSync.js‎

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
'use strict';
2+
3+
constcommon=require('../common');
4+
constfs=require('fs');
5+
constpath=require('path');
6+
consttmpdir=require('../../test/common/tmpdir');
7+
tmpdir.refresh();
8+
9+
consttestFiles=fs.readdirSync('test',{withFileTypes: true})
10+
.filter((f)=>f.isDirectory())
11+
.map((f)=>path.join(f.path,f.name));
12+
constbench=common.createBenchmark(main,{
13+
type: ['existing','non-existing'],
14+
n: [1e3],
15+
});
16+
17+
functionmain({ n, type }){
18+
letfiles;
19+
20+
switch(type){
21+
case'existing':
22+
files=testFiles;
23+
break;
24+
case'non-existing':
25+
files=[tmpdir.resolve(`.non-existing-file-${Date.now()}`)];
26+
break;
27+
default:
28+
newError('Invalid type');
29+
}
30+
31+
bench.start();
32+
for(leti=0;i<n;i++){
33+
for(letj=0;j<files.length;j++){
34+
try{
35+
constdir=fs.opendirSync(files[j]);
36+
dir.closeSync();
37+
}catch{
38+
// do nothing
39+
}
40+
}
41+
}
42+
bench.end(n);
43+
}

‎lib/internal/fs/dir.js‎

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -322,18 +322,11 @@ function opendir(path, options, callback) {
322322

323323
functionopendirSync(path,options){
324324
path=getValidatedPath(path);
325-
options=getOptions(options,{
326-
encoding: 'utf8',
327-
});
325+
options=getOptions(options,{encoding: 'utf8'});
328326

329-
constctx={ path };
330-
consthandle=dirBinding.opendir(
327+
consthandle=dirBinding.opendirSync(
331328
pathModule.toNamespacedPath(path),
332-
options.encoding,
333-
undefined,
334-
ctx,
335329
);
336-
handleErrorFromBinding(ctx);
337330

338331
returnnewDir(handle,path,options);
339332
}

‎src/node_dir.cc‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,32 @@ static void OpenDir(const FunctionCallbackInfo<Value>& args) {
397397
}
398398
}
399399

400+
staticvoidOpenDirSync(const FunctionCallbackInfo<Value>& args) {
401+
Environment* env = Environment::GetCurrent(args);
402+
Isolate* isolate = env->isolate();
403+
404+
CHECK_GE(args.Length(), 1);
405+
406+
BufferValue path(isolate, args[0]);
407+
CHECK_NOT_NULL(*path);
408+
THROW_IF_INSUFFICIENT_PERMISSIONS(
409+
env, permission::PermissionScope::kFileSystemRead, path.ToStringView());
410+
411+
uv_fs_t req;
412+
auto make = OnScopeLeave([&req]() { uv_fs_req_cleanup(&req); });
413+
FS_DIR_SYNC_TRACE_BEGIN(opendir);
414+
int err = uv_fs_opendir(nullptr, &req, *path, nullptr);
415+
FS_DIR_SYNC_TRACE_END(opendir);
416+
if (err < 0) {
417+
return env->ThrowUVException(err, "opendir");
418+
}
419+
420+
uv_dir_t* dir = static_cast<uv_dir_t*>(req.ptr);
421+
DirHandle* handle = DirHandle::New(env, dir);
422+
423+
args.GetReturnValue().Set(handle->object().As<Value>());
424+
}
425+
400426
voidInitialize(Local<Object> target,
401427
Local<Value> unused,
402428
Local<Context> context,
@@ -405,6 +431,7 @@ void Initialize(Local<Object> target,
405431
Isolate* isolate = env->isolate();
406432

407433
SetMethod(context, target, "opendir", OpenDir);
434+
SetMethod(context, target, "opendirSync", OpenDirSync);
408435

409436
// Create FunctionTemplate for DirHandle
410437
Local<FunctionTemplate> dir = NewFunctionTemplate(isolate, DirHandle::New);
@@ -419,6 +446,7 @@ void Initialize(Local<Object> target,
419446

420447
voidRegisterExternalReferences(ExternalReferenceRegistry* registry) {
421448
registry->Register(OpenDir);
449+
registry->Register(OpenDirSync);
422450
registry->Register(DirHandle::New);
423451
registry->Register(DirHandle::Read);
424452
registry->Register(DirHandle::Close);

0 commit comments

Comments
 (0)