GeezerVison is showing github.com — fs: improve error performance for `unlinkSync` · nodejs/node@e82e46c
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboard +43Lines changed: 43 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +'use strict'; | | 2 | + | | 3 | +const common = require('../common'); | | 4 | +const fs = require('fs'); | | 5 | +const tmpdir = require('../../test/common/tmpdir'); | | 6 | +tmpdir.refresh(); | | 7 | + | | 8 | +const bench = common.createBenchmark(main, { | | 9 | + type: ['existing', 'non-existing'], | | 10 | + n: [1e3], | | 11 | +}); | | 12 | + | | 13 | +function main({ n, type }) { | | 14 | + let files; | | 15 | + | | 16 | + switch (type) { | | 17 | + case 'existing': | | 18 | + files = []; | | 19 | + | | 20 | + // Populate tmpdir with mock files | | 21 | + for (let i = 0; i < n; i++) { | | 22 | + const path = tmpdir.resolve(`unlinksync-bench-file-${i}`); | | 23 | + fs.writeFileSync(path, 'bench'); | | 24 | + files.push(path); | | 25 | + } | | 26 | + break; | | 27 | + case 'non-existing': | | 28 | + files = new Array(n).fill(tmpdir.resolve(`.non-existing-file-${Date.now()}`)); | | 29 | + break; | | 30 | + default: | | 31 | + new Error('Invalid type'); | | 32 | + } | | 33 | + | | 34 | + bench.start(); | | 35 | + for (let i = 0; i < n; i++) { | | 36 | + try { | | 37 | + fs.unlinkSync(files[i]); | | 38 | + } catch { | | 39 | + // do nothing | | 40 | + } | | 41 | + } | | 42 | + bench.end(n); | | 43 | +} |
Collapse file Copy file name to clipboardExpand all lines: lib/fs.js +1-4Lines changed: 1 addition & 4 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -1850,10 +1850,7 @@ function unlink(path, callback) { | 1850 | 1850 | * @returns {void} | 1851 | 1851 | */ | 1852 | 1852 | function unlinkSync(path) { | 1853 | | - path = getValidatedPath(path); | 1854 | | - const ctx = { path }; | 1855 | | - binding.unlink(pathModule.toNamespacedPath(path), undefined, ctx); | 1856 | | - handleErrorFromBinding(ctx); | | 1853 | + return syncFs.unlink(path); | 1857 | 1854 | } | 1858 | 1855 |
| 1859 | 1856 | /** | |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/fs/sync.js +6Lines changed: 6 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -88,6 +88,11 @@ function close(fd) { | 88 | 88 | return binding.closeSync(fd); | 89 | 89 | } | 90 | 90 |
| | 91 | +function unlink(path) { | | 92 | + path = pathModule.toNamespacedPath(getValidatedPath(path)); | | 93 | + return binding.unlinkSync(path); | | 94 | +} | | 95 | + | 91 | 96 | module.exports = { | 92 | 97 | readFileUtf8, | 93 | 98 | exists, | @@ -97,4 +102,5 @@ module.exports = { | 97 | 102 | statfs, | 98 | 103 | open, | 99 | 104 | close, | | 105 | + unlink, | 100 | 106 | }; |
Collapse file Copy file name to clipboardExpand all lines: src/node_file.cc +23Lines changed: 23 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -1702,6 +1702,27 @@ static void Unlink(const FunctionCallbackInfo<Value>& args) { | 1702 | 1702 | } | 1703 | 1703 | } | 1704 | 1704 |
| | 1705 | +static void UnlinkSync(const FunctionCallbackInfo<Value>& args) { | | 1706 | + Environment* env = Environment::GetCurrent(args); | | 1707 | + | | 1708 | + const int argc = args.Length(); | | 1709 | + CHECK_GE(argc, 1); | | 1710 | + | | 1711 | + BufferValue path(env->isolate(), args[0]); | | 1712 | + CHECK_NOT_NULL(*path); | | 1713 | + THROW_IF_INSUFFICIENT_PERMISSIONS( | | 1714 | + env, permission::PermissionScope::kFileSystemWrite, path.ToStringView()); | | 1715 | + | | 1716 | + uv_fs_t req; | | 1717 | + auto make = OnScopeLeave([&req]() { uv_fs_req_cleanup(&req); }); | | 1718 | + FS_SYNC_TRACE_BEGIN(unlink); | | 1719 | + int err = uv_fs_unlink(nullptr, &req, *path, nullptr); | | 1720 | + FS_SYNC_TRACE_END(unlink); | | 1721 | + if (err < 0) { | | 1722 | + return env->ThrowUVException(err, "unlink", nullptr, *path); | | 1723 | + } | | 1724 | +} | | 1725 | + | 1705 | 1726 | static void RMDir(const FunctionCallbackInfo<Value>& args) { | 1706 | 1727 | Environment* env = Environment::GetCurrent(args); | 1707 | 1728 |
| @@ -3425,6 +3446,7 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data, | 3425 | 3446 | SetMethod(isolate, target, "symlink", Symlink); | 3426 | 3447 | SetMethod(isolate, target, "readlink", ReadLink); | 3427 | 3448 | SetMethod(isolate, target, "unlink", Unlink); | | 3449 | + SetMethod(isolate, target, "unlinkSync", UnlinkSync); | 3428 | 3450 | SetMethod(isolate, target, "writeBuffer", WriteBuffer); | 3429 | 3451 | SetMethod(isolate, target, "writeBuffers", WriteBuffers); | 3430 | 3452 | SetMethod(isolate, target, "writeString", WriteString); | @@ -3550,6 +3572,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { | 3550 | 3572 | registry->Register(Symlink); | 3551 | 3573 | registry->Register(ReadLink); | 3552 | 3574 | registry->Register(Unlink); | | 3575 | + registry->Register(UnlinkSync); | 3553 | 3576 | registry->Register(WriteBuffer); | 3554 | 3577 | registry->Register(WriteBuffers); | 3555 | 3578 | registry->Register(WriteString); | |
|