@@ -2,48 +2,59 @@ use crate::crates::{lists::List, Crate};
22use crate :: dirs:: WORK_DIR ;
33use crate :: prelude:: * ;
44use crates_index:: GitIndex ;
5+ use rayon:: iter:: ParallelIterator ;
56use std:: collections:: HashMap ;
67use std:: fs:: { self } ;
8+ use std:: sync:: Mutex ;
79
810pub ( crate ) struct RegistryList ;
911
1012impl List for RegistryList {
1113 const NAME : & ' static str = "registry" ;
1214
1315 fn fetch ( & self ) -> Fallible < Vec < Crate > > {
14- let mut list = Vec :: new ( ) ;
15- let mut counts = HashMap :: new ( ) ;
16+ let counts = Mutex :: new ( HashMap :: new ( ) ) ;
1617
18+ debug ! ( "updating git index" ) ;
1719 fs:: create_dir_all ( & * WORK_DIR ) ?;
1820 let mut index = GitIndex :: with_path (
1921 WORK_DIR . join ( "crates.io-index" ) ,
2022 "https://github.com/rust-lang/crates.io-index" ,
2123 ) ?;
2224 index. update ( ) ?;
25+ debug ! ( "collecting crate information" ) ;
2326
24- for krate in index. crates ( ) {
25- // The versions() method returns the list of published versions starting from the
26- // first one, so its output is reversed to check the latest first
27- for version in krate. versions ( ) . iter ( ) . rev ( ) {
28- // Try every version until we find a non-yanked one. If all the versions are
29- // yanked the crate is automatically skipped
30- if !version. is_yanked ( ) {
31- // Increment the counters of this crate's dependencies
32- for dependency in version. dependencies ( ) {
33- let count = counts. entry ( dependency. name ( ) . to_string ( ) ) . or_insert ( 0 ) ;
34- * count += 1 ;
35- }
36-
37- list. push ( Crate :: Registry ( RegistryCrate {
38- name : krate. name ( ) . to_string ( ) ,
39- version : version. version ( ) . to_string ( ) ,
40- } ) ) ;
41- break ;
42- }
43- }
44- }
27+ let mut list: Vec < _ > = index
28+ . crates_parallel ( )
29+ . filter_map ( |krate| {
30+ let krate = krate. as_ref ( ) . unwrap ( ) ;
31+ // The versions() method returns the list of published versions starting from the
32+ // first one, so its output is reversed to check the latest first
33+ krate
34+ . versions ( )
35+ . iter ( )
36+ . rev ( )
37+ // Don't include yanked versions. If all versions are
38+ // yanked, then the crate is skipped.
39+ . filter ( |version| !version. is_yanked ( ) )
40+ . map ( |version| {
41+ // Increment the counters of this crate's dependencies
42+ let mut counts = counts. lock ( ) . unwrap ( ) ;
43+ for dependency in version. dependencies ( ) {
44+ let count = counts. entry ( dependency. name ( ) . to_string ( ) ) . or_insert ( 0 ) ;
45+ * count += 1 ;
46+ }
47+ Crate :: Registry ( RegistryCrate {
48+ name : krate. name ( ) . to_string ( ) ,
49+ version : version. version ( ) . to_string ( ) ,
50+ } )
51+ } )
52+ . next ( )
53+ } )
54+ . collect ( ) ;
4555
4656 // Ensure the list is sorted by popularity
57+ let counts = counts. lock ( ) . unwrap ( ) ;
4758 list. sort_by ( |a, b| {
4859 if let ( Crate :: Registry ( ref a) , Crate :: Registry ( ref b) ) = ( a, b) {
4960 let count_a = counts. get ( & a. name ) . cloned ( ) . unwrap_or ( 0 ) ;
0 commit comments