Skip to content

Commit f822ca4

Browse files
committed
fs: improve performance for fs.rmdirSync
1 parent 740ca54 commit f822ca4

File tree

3 files changed

+67
-3
lines changed

3 files changed

+67
-3
lines changed

benchmark/fs/bench-rmdirSync.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const fs = require('fs');
5+
const path = require('path');
6+
const tmpdir = require('../../test/common/tmpdir');
7+
tmpdir.refresh();
8+
9+
const testFiles = fs.readdirSync('test', { withFileTypes: true })
10+
.filter((f) => f.isDirectory())
11+
.map((f) => path.join(f.path, f.name));
12+
const bench = common.createBenchmark(main, {
13+
type: ['existing', 'non-existing'],
14+
n: [1e3],
15+
});
16+
17+
function main({ n, type }) {
18+
let files;
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+
new Error('Invalid type');
29+
}
30+
31+
bench.start();
32+
for (let i = 0; i < n; i++) {
33+
for (let j = 0; j < files.length; j++) {
34+
try {
35+
const dir = fs.rmdirSync(files[j]);
36+
dir.closeSync();
37+
} catch {
38+
// do nothing
39+
}
40+
}
41+
}
42+
bench.end(n);
43+
}

lib/fs.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,9 +1207,7 @@ function rmdirSync(path, options) {
12071207
validateRmdirOptions(options);
12081208
}
12091209

1210-
const ctx = { path };
1211-
binding.rmdir(pathModule.toNamespacedPath(path), undefined, ctx);
1212-
return handleErrorFromBinding(ctx);
1210+
return binding.rmdirSync(pathModule.toNamespacedPath(path));
12131211
}
12141212

12151213
/**

src/node_file.cc

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1694,6 +1694,27 @@ static void RMDir(const FunctionCallbackInfo<Value>& args) {
16941694
}
16951695
}
16961696

1697+
static void RMDirSync(const FunctionCallbackInfo<Value>& args) {
1698+
Environment* env = Environment::GetCurrent(args);
1699+
1700+
const int argc = args.Length();
1701+
CHECK_GE(argc, 1);
1702+
1703+
BufferValue path(env->isolate(), args[0]);
1704+
CHECK_NOT_NULL(*path);
1705+
THROW_IF_INSUFFICIENT_PERMISSIONS(
1706+
env, permission::PermissionScope::kFileSystemWrite, path.ToStringView());
1707+
1708+
uv_fs_t req;
1709+
auto make = OnScopeLeave([&req]() { uv_fs_req_cleanup(&req); });
1710+
FS_SYNC_TRACE_BEGIN(rmdir);
1711+
int err = uv_fs_rmdir(nullptr, &req, *path, nullptr);
1712+
FS_SYNC_TRACE_END(rmdir);
1713+
if (err < 0) {
1714+
return env->ThrowUVException(err, "rmdir", nullptr, *path);
1715+
}
1716+
}
1717+
16971718
int MKDirpSync(uv_loop_t* loop,
16981719
uv_fs_t* req,
16991720
const std::string& path,
@@ -3365,6 +3386,7 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data,
33653386
SetMethod(isolate, target, "rename", Rename);
33663387
SetMethod(isolate, target, "ftruncate", FTruncate);
33673388
SetMethod(isolate, target, "rmdir", RMDir);
3389+
SetMethodNoSideEffect(isolate, target, "rmdirSync", RMDirSync);
33683390
SetMethod(isolate, target, "mkdir", MKDir);
33693391
SetMethod(isolate, target, "readdir", ReadDir);
33703392
SetMethod(isolate, target, "internalModuleReadJSON", InternalModuleReadJSON);
@@ -3490,6 +3512,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
34903512
registry->Register(Rename);
34913513
registry->Register(FTruncate);
34923514
registry->Register(RMDir);
3515+
registry->Register(RMDirSync);
34933516
registry->Register(MKDir);
34943517
registry->Register(ReadDir);
34953518
registry->Register(InternalModuleReadJSON);

0 commit comments

Comments
 (0)