mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 15:04:11 -05:00
perf(node/fs): faster existsSync
when not exists (#21458)
This commit is contained in:
parent
9eb25e3cff
commit
a24d3e8763
7 changed files with 93 additions and 13 deletions
|
@ -3,7 +3,8 @@
|
||||||
import { assert, assertThrows } from "../../../test_util/std/assert/mod.ts";
|
import { assert, assertThrows } from "../../../test_util/std/assert/mod.ts";
|
||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
import { tmpdir } from "node:os";
|
import { tmpdir } from "node:os";
|
||||||
import { mkdtempSync, readFileSync, writeFileSync } from "node:fs";
|
import { existsSync, mkdtempSync, readFileSync, writeFileSync } from "node:fs";
|
||||||
|
import { pathToAbsoluteFileUrl } from "../unit/test_util.ts";
|
||||||
|
|
||||||
Deno.test(
|
Deno.test(
|
||||||
"[node/fs writeFileSync] write file without option",
|
"[node/fs writeFileSync] write file without option",
|
||||||
|
@ -43,3 +44,39 @@ Deno.test(
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Deno.test(
|
||||||
|
"[node/fs existsSync] path",
|
||||||
|
{ permissions: { read: true } },
|
||||||
|
() => {
|
||||||
|
assert(existsSync("cli/tests/testdata/assets/fixture.json"));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
Deno.test(
|
||||||
|
"[node/fs existsSync] url",
|
||||||
|
{ permissions: { read: true } },
|
||||||
|
() => {
|
||||||
|
assert(existsSync(
|
||||||
|
pathToAbsoluteFileUrl("cli/tests/testdata/assets/fixture.json"),
|
||||||
|
));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
Deno.test(
|
||||||
|
"[node/fs existsSync] no permission",
|
||||||
|
{ permissions: { read: false } },
|
||||||
|
() => {
|
||||||
|
assertThrows(() => {
|
||||||
|
existsSync("cli/tests/testdata/assets/fixture.json");
|
||||||
|
}, Deno.errors.PermissionDenied);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
Deno.test(
|
||||||
|
"[node/fs existsSync] not exists",
|
||||||
|
{ permissions: { read: true } },
|
||||||
|
() => {
|
||||||
|
assert(!existsSync("bad_filename"));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
|
@ -50,7 +50,15 @@ pub trait NodePermissions {
|
||||||
url: &Url,
|
url: &Url,
|
||||||
api_name: &str,
|
api_name: &str,
|
||||||
) -> Result<(), AnyError>;
|
) -> Result<(), AnyError>;
|
||||||
fn check_read(&self, path: &Path) -> Result<(), AnyError>;
|
#[inline(always)]
|
||||||
|
fn check_read(&self, path: &Path) -> Result<(), AnyError> {
|
||||||
|
self.check_read_with_api_name(path, None)
|
||||||
|
}
|
||||||
|
fn check_read_with_api_name(
|
||||||
|
&self,
|
||||||
|
path: &Path,
|
||||||
|
api_name: Option<&str>,
|
||||||
|
) -> Result<(), AnyError>;
|
||||||
fn check_sys(&self, kind: &str, api_name: &str) -> Result<(), AnyError>;
|
fn check_sys(&self, kind: &str, api_name: &str) -> Result<(), AnyError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +72,11 @@ impl NodePermissions for AllowAllNodePermissions {
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), AnyError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn check_read(&self, _path: &Path) -> Result<(), AnyError> {
|
fn check_read_with_api_name(
|
||||||
|
&self,
|
||||||
|
_path: &Path,
|
||||||
|
_api_name: Option<&str>,
|
||||||
|
) -> Result<(), AnyError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn check_sys(&self, _kind: &str, _api_name: &str) -> Result<(), AnyError> {
|
fn check_sys(&self, _kind: &str, _api_name: &str) -> Result<(), AnyError> {
|
||||||
|
@ -227,6 +239,7 @@ deno_core::extension!(deno_node,
|
||||||
ops::crypto::x509::op_node_x509_get_valid_to,
|
ops::crypto::x509::op_node_x509_get_valid_to,
|
||||||
ops::crypto::x509::op_node_x509_get_serial_number,
|
ops::crypto::x509::op_node_x509_get_serial_number,
|
||||||
ops::crypto::x509::op_node_x509_key_usage,
|
ops::crypto::x509::op_node_x509_key_usage,
|
||||||
|
ops::fs::op_node_fs_exists_sync<P>,
|
||||||
ops::winerror::op_node_sys_to_uv_error,
|
ops::winerror::op_node_sys_to_uv_error,
|
||||||
ops::v8::op_v8_cached_data_version_tag,
|
ops::v8::op_v8_cached_data_version_tag,
|
||||||
ops::v8::op_v8_get_heap_statistics,
|
ops::v8::op_v8_get_heap_statistics,
|
||||||
|
|
26
ext/node/ops/fs.rs
Normal file
26
ext/node/ops/fs.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use deno_core::error::AnyError;
|
||||||
|
use deno_core::op2;
|
||||||
|
use deno_core::OpState;
|
||||||
|
use deno_fs::FileSystemRc;
|
||||||
|
|
||||||
|
use crate::NodePermissions;
|
||||||
|
|
||||||
|
#[op2(fast)]
|
||||||
|
pub fn op_node_fs_exists_sync<P>(
|
||||||
|
state: &mut OpState,
|
||||||
|
#[string] path: String,
|
||||||
|
) -> Result<bool, AnyError>
|
||||||
|
where
|
||||||
|
P: NodePermissions + 'static,
|
||||||
|
{
|
||||||
|
let path = PathBuf::from(path);
|
||||||
|
state
|
||||||
|
.borrow_mut::<P>()
|
||||||
|
.check_read_with_api_name(&path, Some("node:fs.existsSync()"))?;
|
||||||
|
let fs = state.borrow::<FileSystemRc>();
|
||||||
|
Ok(fs.lstat_sync(&path).is_ok())
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
pub mod crypto;
|
pub mod crypto;
|
||||||
|
pub mod fs;
|
||||||
pub mod http;
|
pub mod http;
|
||||||
pub mod http2;
|
pub mod http2;
|
||||||
pub mod idna;
|
pub mod idna;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
// TODO(petamoriken): enable prefer-primordials for node polyfills
|
// TODO(petamoriken): enable prefer-primordials for node polyfills
|
||||||
// deno-lint-ignore-file prefer-primordials
|
// deno-lint-ignore-file prefer-primordials
|
||||||
|
const core = globalThis.__bootstrap.core;
|
||||||
import { pathFromURL } from "ext:deno_web/00_infra.js";
|
import { pathFromURL } from "ext:deno_web/00_infra.js";
|
||||||
|
|
||||||
type ExistsCallback = (exists: boolean) => void;
|
type ExistsCallback = (exists: boolean) => void;
|
||||||
|
@ -35,10 +35,5 @@ Object.defineProperty(exists, kCustomPromisifiedSymbol, {
|
||||||
*/
|
*/
|
||||||
export function existsSync(path: string | URL): boolean {
|
export function existsSync(path: string | URL): boolean {
|
||||||
path = path instanceof URL ? pathFromURL(path) : path;
|
path = path instanceof URL ? pathFromURL(path) : path;
|
||||||
try {
|
return core.ops.op_node_fs_exists_sync(path);
|
||||||
Deno.lstatSync(path);
|
|
||||||
return true;
|
|
||||||
} catch (_err) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1376,8 +1376,12 @@ impl deno_node::NodePermissions for PermissionsContainer {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn check_read(&self, path: &Path) -> Result<(), AnyError> {
|
fn check_read_with_api_name(
|
||||||
self.0.lock().read.check(path, None)
|
&self,
|
||||||
|
path: &Path,
|
||||||
|
api_name: Option<&str>,
|
||||||
|
) -> Result<(), AnyError> {
|
||||||
|
self.0.lock().read.check(path, api_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_sys(&self, kind: &str, api_name: &str) -> Result<(), AnyError> {
|
fn check_sys(&self, kind: &str, api_name: &str) -> Result<(), AnyError> {
|
||||||
|
|
|
@ -76,7 +76,11 @@ impl deno_node::NodePermissions for Permissions {
|
||||||
) -> Result<(), deno_core::error::AnyError> {
|
) -> Result<(), deno_core::error::AnyError> {
|
||||||
unreachable!("snapshotting!")
|
unreachable!("snapshotting!")
|
||||||
}
|
}
|
||||||
fn check_read(&self, _p: &Path) -> Result<(), deno_core::error::AnyError> {
|
fn check_read_with_api_name(
|
||||||
|
&self,
|
||||||
|
_p: &Path,
|
||||||
|
_api_name: Option<&str>,
|
||||||
|
) -> Result<(), deno_core::error::AnyError> {
|
||||||
unreachable!("snapshotting!")
|
unreachable!("snapshotting!")
|
||||||
}
|
}
|
||||||
fn check_sys(
|
fn check_sys(
|
||||||
|
|
Loading…
Reference in a new issue