Skip to content

Commit 82a33b9

Browse files
committed
Cache try_package_path
1 parent 9676953 commit 82a33b9

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

rewatch/src/build.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ pub fn initialize_build(
157157
}
158158

159159
let mut build_state = BuildState::new(project_context, packages, bsc_path);
160+
// Clear memoization cache at the start of each build
161+
helpers::reset_try_package_path_cache();
160162
packages::parse_packages(&mut build_state);
161163
let timing_source_files_elapsed = timing_source_files.elapsed();
162164

rewatch/src/helpers.rs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,32 @@ use crate::build::packages;
22
use crate::config::Config;
33
use crate::helpers;
44
use crate::project_context::ProjectContext;
5+
use ahash::AHashMap;
56
use anyhow::anyhow;
67
use std::ffi::OsString;
78
use std::fs;
89
use std::fs::File;
910
use std::io::Read;
1011
use std::io::{self, BufRead};
1112
use std::path::{Component, Path, PathBuf};
13+
use std::sync::{LazyLock, RwLock};
1214
use std::time::{SystemTime, UNIX_EPOCH};
1315

1416
pub type StdErr = String;
1517

1618
pub mod deserialize;
1719

20+
// Thread-safe memoization cache for try_package_path results per build.
21+
// Keyed by "{package_config.name}+{package_name}". Value is Some(path) or None (not found).
22+
static TRY_PACKAGE_PATH_CACHE: LazyLock<RwLock<AHashMap<String, Option<PathBuf>>>> =
23+
LazyLock::new(|| RwLock::new(AHashMap::new()));
24+
25+
pub fn reset_try_package_path_cache() {
26+
if let Ok(mut map) = TRY_PACKAGE_PATH_CACHE.write() {
27+
map.clear();
28+
}
29+
}
30+
1831
pub mod emojis {
1932
use console::Emoji;
2033
pub static COMMAND: Emoji<'_, '_> = Emoji("🏃 ", "");
@@ -114,6 +127,19 @@ pub fn try_package_path(
114127
project_context: &ProjectContext,
115128
package_name: &str,
116129
) -> anyhow::Result<PathBuf> {
130+
// First, attempt to serve from cache
131+
let cache_key = format!("{}+{}", package_config.name, package_name);
132+
if let Ok(cache) = TRY_PACKAGE_PATH_CACHE.read() {
133+
if let Some(cached) = cache.get(&cache_key) {
134+
return match cached {
135+
Some(path) => Ok(path.clone()),
136+
None => Err(anyhow!(
137+
"The package \"{package_name}\" is not found (are node_modules up-to-date?)..."
138+
)),
139+
};
140+
}
141+
}
142+
117143
// package folder + node_modules + package_name
118144
// This can happen in the following scenario:
119145
// The ProjectContext has a MonoRepoContext::MonorepoRoot.
@@ -147,7 +173,7 @@ pub fn try_package_path(
147173

148174
// root folder + node_modules + package_name
149175
let path_from_root = package_path(project_context.get_root_path(), package_name);
150-
if path_from_current_package.exists() {
176+
let result = if path_from_current_package.exists() {
151177
Ok(path_from_current_package)
152178
} else if path_from_current_config.exists() {
153179
Ok(path_from_current_config)
@@ -157,7 +183,21 @@ pub fn try_package_path(
157183
Err(anyhow!(
158184
"The package \"{package_name}\" is not found (are node_modules up-to-date?)..."
159185
))
186+
};
187+
188+
// Store in cache
189+
if let Ok(mut cache) = TRY_PACKAGE_PATH_CACHE.write() {
190+
match &result {
191+
Ok(path) => {
192+
cache.insert(cache_key, Some(path.clone()));
193+
}
194+
Err(_) => {
195+
cache.insert(cache_key, None);
196+
}
197+
}
160198
}
199+
200+
result
161201
}
162202

163203
pub fn get_abs_path(path: &Path) -> PathBuf {

0 commit comments

Comments
 (0)