From 2bb8edb13cb0c2a114d8daf26cea0a4b1cda1502 Mon Sep 17 00:00:00 2001 From: Boshen Date: Sat, 22 Jul 2023 21:13:59 +0800 Subject: [PATCH] perf(resolver): cache canonicalized path (#584) --- crates/oxc_resolver/src/cache.rs | 31 +++++++++++++++++++++---------- crates/oxc_resolver/src/lib.rs | 6 +++--- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/crates/oxc_resolver/src/cache.rs b/crates/oxc_resolver/src/cache.rs index e9a6de4f7..0a00a94c2 100644 --- a/crates/oxc_resolver/src/cache.rs +++ b/crates/oxc_resolver/src/cache.rs @@ -1,7 +1,7 @@ use std::{ hash::BuildHasherDefault, path::{Path, PathBuf}, - sync::Arc, + sync::{Arc, OnceLock}, }; use dashmap::DashMap; @@ -9,6 +9,12 @@ use rustc_hash::FxHasher; use crate::{package_json::PackageJson, FileMetadata, FileSystem, ResolveError}; +#[derive(Debug, Clone, Default)] +pub struct PathData { + meta: OnceLock>, + symlink: OnceLock>, +} + pub type PackageJsonCache = DashMap< Box, Result>, ResolveError>, @@ -17,7 +23,7 @@ pub type PackageJsonCache = DashMap< pub struct Cache { fs: Fs, - cache: DashMap, Option, BuildHasherDefault>, + cache: DashMap>, package_json_cache: PackageJsonCache, } @@ -37,20 +43,25 @@ impl Cache { } fn metadata_cached(&self, path: &Path) -> Option { - if let Some(result) = self.cache.get(path) { - return *result; - } - let file_metadata = self.fs.metadata(path).ok(); - self.cache.insert(path.to_path_buf().into_boxed_path(), file_metadata); - file_metadata + *self + .cache + .entry(path.to_path_buf()) + .or_default() + .meta + .get_or_init(|| self.fs.metadata(path).ok()) } pub fn is_file(&self, path: &Path) -> bool { self.metadata_cached(path).is_some_and(|m| m.is_file) } - pub fn canonicalize(&self, path: PathBuf) -> PathBuf { - self.fs.canonicalize(&path).unwrap_or(path) + pub fn canonicalize(&self, path: &Path) -> Option { + self.cache + .entry(path.to_path_buf()) + .or_default() + .symlink + .get_or_init(|| self.fs.canonicalize(path).ok()) + .clone() } /// # Errors diff --git a/crates/oxc_resolver/src/lib.rs b/crates/oxc_resolver/src/lib.rs index 8fdbba5fc..fc342dd7f 100644 --- a/crates/oxc_resolver/src/lib.rs +++ b/crates/oxc_resolver/src/lib.rs @@ -89,7 +89,7 @@ impl ResolverGeneric { result? } }; - let path = self.load_symlink(path); + let path = self.load_symlink(&path).unwrap_or(path); Ok(Resolution { path, query: request.query.map(ToString::to_string), @@ -183,8 +183,8 @@ impl ResolverGeneric { Ok(None) } - fn load_symlink(&self, path: PathBuf) -> PathBuf { - if self.options.symlinks { self.cache.canonicalize(path) } else { path } + fn load_symlink(&self, path: &Path) -> Option { + if self.options.symlinks { self.cache.canonicalize(path) } else { None } } #[allow(clippy::unnecessary_wraps)]