@@ -19,7 +19,7 @@ pub struct WindowsRegistry {
1919 #[ allow( dead_code) ]
2020 conda_locator : Arc < dyn CondaLocator > ,
2121 #[ allow( dead_code) ]
22- search_result : Arc < Mutex < Option < LocatorResult > > > ,
22+ search_result : Arc < Mutex < Option < Arc < LocatorResult > > > > ,
2323}
2424
2525impl WindowsRegistry {
@@ -30,17 +30,17 @@ impl WindowsRegistry {
3030 }
3131 }
3232 #[ cfg( windows) ]
33- fn find_with_cache ( & self , reporter : Option < & dyn Reporter > ) -> Option < LocatorResult > {
33+ fn find_with_cache ( & self , reporter : Option < & dyn Reporter > ) -> Option < Arc < LocatorResult > > {
3434 let mut result = self
3535 . search_result
3636 . lock ( )
3737 . expect ( "search_result mutex poisoned" ) ;
38- if let Some ( result) = result. clone ( ) {
39- return Some ( result) ;
38+ if let Some ( result) = result. as_ref ( ) {
39+ return Some ( Arc :: clone ( result) ) ;
4040 }
4141
42- let registry_result = get_registry_pythons ( & self . conda_locator , & reporter) ;
43- result. replace ( registry_result . clone ( ) ) ;
42+ let registry_result = Arc :: new ( get_registry_pythons ( & self . conda_locator , & reporter) ) ;
43+ result. replace ( Arc :: clone ( & registry_result ) ) ;
4444
4545 Some ( registry_result)
4646 }
@@ -111,10 +111,10 @@ impl Locator for WindowsRegistry {
111111 #[ cfg( windows) ]
112112 if let Some ( result) = self . find_with_cache ( None ) {
113113 // Find the same env here
114- for found_env in result. environments {
114+ for found_env in & result. environments {
115115 if let Some ( ref python_executable_path) = found_env. executable {
116116 if python_executable_path == & env. executable {
117- return Some ( found_env) ;
117+ return Some ( found_env. clone ( ) ) ;
118118 }
119119 }
120120 }
@@ -135,12 +135,15 @@ impl Locator for WindowsRegistry {
135135 // replay the cached environments/managers to the reporter
136136 // ourselves — otherwise WindowsRegistry discoveries would silently
137137 // disappear on every refresh after the first.
138+ //
139+ // The cache stores an `Arc<LocatorResult>`, so the lookup is a
140+ // cheap pointer clone — no deep copy of the underlying vectors.
138141 let cached = {
139142 let result = self
140143 . search_result
141144 . lock ( )
142145 . expect ( "search_result mutex poisoned" ) ;
143- result. clone ( )
146+ result. as_ref ( ) . map ( Arc :: clone )
144147 } ;
145148 if let Some ( cached) = cached {
146149 for manager in & cached. managers {
@@ -221,24 +224,28 @@ mod tests {
221224 let shared = create_locator ( ) ;
222225 let refreshed = create_locator ( ) ;
223226
224- shared. search_result . lock ( ) . unwrap ( ) . replace ( LocatorResult {
225- managers : vec ! [ ] ,
226- environments : vec ! [ PythonEnvironment {
227- name: Some ( "stale" . to_string( ) ) ,
228- ..Default :: default ( )
229- } ] ,
230- } ) ;
227+ shared
228+ . search_result
229+ . lock ( )
230+ . unwrap ( )
231+ . replace ( Arc :: new ( LocatorResult {
232+ managers : vec ! [ ] ,
233+ environments : vec ! [ PythonEnvironment {
234+ name: Some ( "stale" . to_string( ) ) ,
235+ ..Default :: default ( )
236+ } ] ,
237+ } ) ) ;
231238 refreshed
232239 . search_result
233240 . lock ( )
234241 . unwrap ( )
235- . replace ( LocatorResult {
242+ . replace ( Arc :: new ( LocatorResult {
236243 managers : vec ! [ ] ,
237244 environments : vec ! [ PythonEnvironment {
238245 name: Some ( "fresh" . to_string( ) ) ,
239246 ..Default :: default ( )
240247 } ] ,
241- } ) ;
248+ } ) ) ;
242249
243250 shared. sync_refresh_state_from ( & refreshed, & RefreshStateSyncScope :: Full ) ;
244251
@@ -251,24 +258,28 @@ mod tests {
251258 let shared = create_locator ( ) ;
252259 let refreshed = create_locator ( ) ;
253260
254- shared. search_result . lock ( ) . unwrap ( ) . replace ( LocatorResult {
255- managers : vec ! [ ] ,
256- environments : vec ! [ PythonEnvironment {
257- name: Some ( "stale" . to_string( ) ) ,
258- ..Default :: default ( )
259- } ] ,
260- } ) ;
261+ shared
262+ . search_result
263+ . lock ( )
264+ . unwrap ( )
265+ . replace ( Arc :: new ( LocatorResult {
266+ managers : vec ! [ ] ,
267+ environments : vec ! [ PythonEnvironment {
268+ name: Some ( "stale" . to_string( ) ) ,
269+ ..Default :: default ( )
270+ } ] ,
271+ } ) ) ;
261272 refreshed
262273 . search_result
263274 . lock ( )
264275 . unwrap ( )
265- . replace ( LocatorResult {
276+ . replace ( Arc :: new ( LocatorResult {
266277 managers : vec ! [ ] ,
267278 environments : vec ! [ PythonEnvironment {
268279 name: Some ( "fresh" . to_string( ) ) ,
269280 ..Default :: default ( )
270281 } ] ,
271- } ) ;
282+ } ) ) ;
272283
273284 shared. sync_refresh_state_from ( & refreshed, & RefreshStateSyncScope :: Workspace ) ;
274285
@@ -281,24 +292,28 @@ mod tests {
281292 let shared = create_locator ( ) ;
282293 let refreshed = create_locator ( ) ;
283294
284- shared. search_result . lock ( ) . unwrap ( ) . replace ( LocatorResult {
285- managers : vec ! [ ] ,
286- environments : vec ! [ PythonEnvironment {
287- name: Some ( "stale" . to_string( ) ) ,
288- ..Default :: default ( )
289- } ] ,
290- } ) ;
295+ shared
296+ . search_result
297+ . lock ( )
298+ . unwrap ( )
299+ . replace ( Arc :: new ( LocatorResult {
300+ managers : vec ! [ ] ,
301+ environments : vec ! [ PythonEnvironment {
302+ name: Some ( "stale" . to_string( ) ) ,
303+ ..Default :: default ( )
304+ } ] ,
305+ } ) ) ;
291306 refreshed
292307 . search_result
293308 . lock ( )
294309 . unwrap ( )
295- . replace ( LocatorResult {
310+ . replace ( Arc :: new ( LocatorResult {
296311 managers : vec ! [ ] ,
297312 environments : vec ! [ PythonEnvironment {
298313 name: Some ( "fresh" . to_string( ) ) ,
299314 ..Default :: default ( )
300315 } ] ,
301- } ) ;
316+ } ) ) ;
302317
303318 shared. sync_refresh_state_from (
304319 & refreshed,
@@ -307,13 +322,17 @@ mod tests {
307322 let result = shared. search_result . lock ( ) . unwrap ( ) . clone ( ) . unwrap ( ) ;
308323 assert_eq ! ( result. environments[ 0 ] . name. as_deref( ) , Some ( "fresh" ) ) ;
309324
310- shared. search_result . lock ( ) . unwrap ( ) . replace ( LocatorResult {
311- managers : vec ! [ ] ,
312- environments : vec ! [ PythonEnvironment {
313- name: Some ( "stale" . to_string( ) ) ,
314- ..Default :: default ( )
315- } ] ,
316- } ) ;
325+ shared
326+ . search_result
327+ . lock ( )
328+ . unwrap ( )
329+ . replace ( Arc :: new ( LocatorResult {
330+ managers : vec ! [ ] ,
331+ environments : vec ! [ PythonEnvironment {
332+ name: Some ( "stale" . to_string( ) ) ,
333+ ..Default :: default ( )
334+ } ] ,
335+ } ) ) ;
317336
318337 shared. sync_refresh_state_from (
319338 & refreshed,
@@ -402,7 +421,7 @@ mod tests {
402421 . search_result
403422 . lock ( )
404423 . unwrap ( )
405- . replace ( cached. clone ( ) ) ;
424+ . replace ( Arc :: new ( cached. clone ( ) ) ) ;
406425
407426 let reporter = RecordingReporter :: default ( ) ;
408427 locator. find ( & reporter) ;
0 commit comments