@@ -174,29 +174,47 @@ pub async fn run(cli: &Cli) -> Result<bool, Box<dyn std::error::Error + Send + S
174174 }
175175
176176 // 3. Resolve ALL versions concurrently across all manifests (Promise.all pattern)
177+ // Create registries once and share across all manifests of the same kind.
177178 let total_deps: usize = manifest_jobs. iter ( ) . map ( |j| j. deps . len ( ) ) . sum ( ) ;
178179 info ! (
179180 manifests = manifest_jobs. len( ) ,
180181 total_deps, "resolving all versions concurrently"
181182 ) ;
182183
184+ let npm_registry = NpmRegistry :: new ( ) ;
185+ let crates_registry = CratesIoRegistry :: new ( ) ;
186+ let pypi_registry = PyPiRegistry :: new ( ) ;
187+
183188 let mut resolve_futures = Vec :: new ( ) ;
184189 for ( job_idx, job) in manifest_jobs. iter ( ) . enumerate ( ) {
185190 if !job. deps . is_empty ( ) {
191+ let npm = & npm_registry;
192+ let crates_io = & crates_registry;
193+ let pypi = & pypi_registry;
186194 resolve_futures. push ( async move {
187- let resolved = resolve_versions ( & job. deps , job. manifest_ref . kind , cli. target ) . await ;
195+ let resolved = match job. manifest_ref . kind {
196+ ManifestKind :: PackageJson => {
197+ npm. resolve_batch ( & job. deps , cli. target ) . await
198+ }
199+ ManifestKind :: CargoToml => {
200+ crates_io. resolve_batch ( & job. deps , cli. target ) . await
201+ }
202+ ManifestKind :: PyProjectToml => {
203+ pypi. resolve_batch ( & job. deps , cli. target ) . await
204+ }
205+ } ;
188206 ( job_idx, resolved)
189207 } ) ;
190208 }
191209 }
192210
193211 let resolved_results: Vec < _ > = futures:: future:: join_all ( resolve_futures) . await ;
194212
195- // Build a map : job_idx -> resolved versions
196- let mut resolved_map: std :: collections :: HashMap < usize , ResolvedBatch > =
197- std :: collections :: HashMap :: new ( ) ;
213+ // Build a vec : job_idx -> resolved versions (dense indices, no HashMap needed)
214+ let mut resolved_map: Vec < Option < ResolvedBatch > > =
215+ ( 0 ..manifest_jobs . len ( ) ) . map ( |_| None ) . collect ( ) ;
198216 for ( job_idx, resolved) in resolved_results {
199- resolved_map. insert ( job_idx, resolved) ;
217+ resolved_map[ job_idx] = Some ( resolved) ;
200218 }
201219
202220 // 4. Print results and apply updates (sequential — needs ordered output)
@@ -213,7 +231,7 @@ pub async fn run(cli: &Cli) -> Result<bool, Box<dyn std::error::Error + Send + S
213231 continue ;
214232 }
215233
216- let resolved = resolved_map. get ( & job_idx ) . map_or ( & [ ] [ .. ] , Vec :: as_slice ) ;
234+ let resolved = resolved_map[ job_idx ] . as_deref ( ) . unwrap_or ( & [ ] ) ;
217235
218236 let success_count = resolved. iter ( ) . filter ( |( _, r) | r. is_ok ( ) ) . count ( ) ;
219237 let fail_count = resolved. len ( ) - success_count;
@@ -282,28 +300,6 @@ fn filter_deps(
282300 . collect ( )
283301}
284302
285- /// Resolve versions for dependencies using the appropriate registry.
286- async fn resolve_versions (
287- deps : & [ DependencySpec ] ,
288- kind : ManifestKind ,
289- target : TargetLevel ,
290- ) -> Vec < ( usize , Result < ResolvedVersion , DcuError > ) > {
291- match kind {
292- ManifestKind :: PackageJson => {
293- let registry = NpmRegistry :: new ( ) ;
294- registry. resolve_batch ( deps, target) . await
295- }
296- ManifestKind :: CargoToml => {
297- let registry = CratesIoRegistry :: new ( ) ;
298- registry. resolve_batch ( deps, target) . await
299- }
300- ManifestKind :: PyProjectToml => {
301- let registry = PyPiRegistry :: new ( ) ;
302- registry. resolve_batch ( deps, target) . await
303- }
304- }
305- }
306-
307303/// Resolved version batch from a registry.
308304type ResolvedBatch = Vec < ( usize , Result < ResolvedVersion , DcuError > ) > ;
309305
0 commit comments