Skip to content

Commit 5bd6e66

Browse files
committed
perf: address Windows Store cache review feedback (PR #418)
1 parent a621489 commit 5bd6e66

File tree

1 file changed

+31
-24
lines changed
  • crates/pet-windows-store/src

1 file changed

+31
-24
lines changed

crates/pet-windows-store/src/lib.rs

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,28 @@ use pet_core::LocatorKind;
1515
use pet_core::{
1616
os_environment::Environment, Locator, RefreshStatePersistence, RefreshStateSyncScope,
1717
};
18+
#[cfg(any(windows, test))]
1819
use pet_fs::path::norm_case;
1920
use std::path::{Path, PathBuf};
2021
use std::sync::{Arc, RwLock};
2122

2223
#[derive(Clone, Debug)]
2324
struct CachedStoreEnvironment {
25+
#[allow(dead_code)]
2426
environment: PythonEnvironment,
2527
#[allow(dead_code)]
2628
normalized_symlinks: Vec<PathBuf>,
2729
}
2830

2931
impl CachedStoreEnvironment {
32+
#[cfg(any(windows, test))]
3033
fn from_environment(environment: PythonEnvironment) -> Self {
3134
let normalized_symlinks = environment
3235
.symlinks
3336
.as_deref()
3437
.unwrap_or_default()
3538
.iter()
36-
.map(normalize_for_comparison)
39+
.map(|path| normalize_for_comparison(path))
3740
.collect();
3841

3942
Self {
@@ -43,7 +46,8 @@ impl CachedStoreEnvironment {
4346
}
4447
}
4548

46-
fn normalize_for_comparison(path: &PathBuf) -> PathBuf {
49+
#[cfg(any(windows, test))]
50+
fn normalize_for_comparison(path: &Path) -> PathBuf {
4751
let normalized = norm_case(path);
4852
let path_str = normalized.to_string_lossy();
4953
if path_str.starts_with(r"\\?\") {
@@ -62,7 +66,7 @@ pub fn is_windows_app_folder_in_program_files(path: &Path) -> bool {
6266
pub struct WindowsStore {
6367
pub env_vars: EnvVariables,
6468
#[allow(dead_code)]
65-
environments: Arc<RwLock<Option<Vec<CachedStoreEnvironment>>>>,
69+
environments: Arc<RwLock<Option<Arc<Vec<CachedStoreEnvironment>>>>>,
6670
}
6771

6872
impl WindowsStore {
@@ -73,7 +77,7 @@ impl WindowsStore {
7377
}
7478
}
7579
#[cfg(windows)]
76-
fn find_with_cache(&self) -> Option<Vec<CachedStoreEnvironment>> {
80+
fn find_with_cache(&self) -> Option<Arc<Vec<CachedStoreEnvironment>>> {
7781
// First check if we have cached results
7882
{
7983
let environments = self.environments.read().unwrap();
@@ -82,11 +86,13 @@ impl WindowsStore {
8286
}
8387
}
8488

85-
let envs = list_store_pythons(&self.env_vars)
86-
.unwrap_or_default()
87-
.into_iter()
88-
.map(CachedStoreEnvironment::from_environment)
89-
.collect::<Vec<_>>();
89+
let envs = Arc::new(
90+
list_store_pythons(&self.env_vars)
91+
.unwrap_or_default()
92+
.into_iter()
93+
.map(CachedStoreEnvironment::from_environment)
94+
.collect::<Vec<_>>(),
95+
);
9096
self.environments.write().unwrap().replace(envs.clone());
9197
Some(envs)
9298
}
@@ -138,9 +144,10 @@ impl Locator for WindowsStore {
138144
use pet_core::python_environment::PythonEnvironmentBuilder;
139145
use pet_virtualenv::is_virtualenv;
140146

141-
// Assume we create a virtual env from a python install,
142-
// Then the exe in the virtual env bin will be a symlink to the homebrew python install.
143-
// Hence the first part of the condition will be true, but the second part will be false.
147+
// A virtual environment created from a Windows Store Python may still have an
148+
// executable path or symlink chain that resolves back to the base Store install.
149+
// Even in that case, the environment itself is a virtualenv and should not be
150+
// classified as a Windows Store environment here.
144151
if is_virtualenv(env) {
145152
return None;
146153
}
@@ -151,7 +158,7 @@ impl Locator for WindowsStore {
151158
.map(|p| normalize_for_comparison(&p))
152159
.collect();
153160
if let Some(environments) = self.find_with_cache() {
154-
for found_env in environments {
161+
for found_env in environments.iter() {
155162
if !found_env.normalized_symlinks.is_empty() {
156163
// Check if we have found this exe.
157164
if list_of_possible_exes
@@ -262,9 +269,9 @@ mod tests {
262269
symlinks: Some(vec![PathBuf::from(format!(r"\\?\{}", symlink.display()))]),
263270
..Default::default()
264271
};
265-
locator.environments.write().unwrap().replace(vec![
272+
locator.environments.write().unwrap().replace(Arc::new(vec![
266273
CachedStoreEnvironment::from_environment(store_environment),
267-
]);
274+
]));
268275

269276
let mut env = PythonEnv::new(symlink.clone(), None, None);
270277
env.symlinks = Some(vec![symlink]);
@@ -284,9 +291,9 @@ mod tests {
284291
symlinks: Some(vec![symlink.clone()]),
285292
..Default::default()
286293
};
287-
locator.environments.write().unwrap().replace(vec![
294+
locator.environments.write().unwrap().replace(Arc::new(vec![
288295
CachedStoreEnvironment::from_environment(store_environment),
289-
]);
296+
]));
290297

291298
let mut env = PythonEnv::new(symlink.clone(), None, None);
292299
env.symlinks = Some(vec![PathBuf::from(format!(r"\\?\{}", symlink.display()))]);
@@ -304,12 +311,12 @@ mod tests {
304311
.environments
305312
.write()
306313
.unwrap()
307-
.replace(vec![cached_environment("stale")]);
314+
.replace(Arc::new(vec![cached_environment("stale")]));
308315
refreshed
309316
.environments
310317
.write()
311318
.unwrap()
312-
.replace(vec![cached_environment("fresh")]);
319+
.replace(Arc::new(vec![cached_environment("fresh")]));
313320

314321
shared.sync_refresh_state_from(&refreshed, &RefreshStateSyncScope::Full);
315322

@@ -327,12 +334,12 @@ mod tests {
327334
.environments
328335
.write()
329336
.unwrap()
330-
.replace(vec![cached_environment("stale")]);
337+
.replace(Arc::new(vec![cached_environment("stale")]));
331338
refreshed
332339
.environments
333340
.write()
334341
.unwrap()
335-
.replace(vec![cached_environment("fresh")]);
342+
.replace(Arc::new(vec![cached_environment("fresh")]));
336343

337344
shared.sync_refresh_state_from(&refreshed, &RefreshStateSyncScope::Workspace);
338345

@@ -350,12 +357,12 @@ mod tests {
350357
.environments
351358
.write()
352359
.unwrap()
353-
.replace(vec![cached_environment("stale")]);
360+
.replace(Arc::new(vec![cached_environment("stale")]));
354361
refreshed
355362
.environments
356363
.write()
357364
.unwrap()
358-
.replace(vec![cached_environment("fresh")]);
365+
.replace(Arc::new(vec![cached_environment("fresh")]));
359366

360367
shared.sync_refresh_state_from(
361368
&refreshed,
@@ -368,7 +375,7 @@ mod tests {
368375
.environments
369376
.write()
370377
.unwrap()
371-
.replace(vec![cached_environment("stale")]);
378+
.replace(Arc::new(vec![cached_environment("stale")]));
372379
shared.sync_refresh_state_from(
373380
&refreshed,
374381
&RefreshStateSyncScope::GlobalFiltered(PythonEnvironmentKind::Conda),

0 commit comments

Comments
 (0)