@@ -2,48 +2,59 @@ use crate::crates::{lists::List, Crate};
2
2
use crate :: dirs:: WORK_DIR ;
3
3
use crate :: prelude:: * ;
4
4
use crates_index:: GitIndex ;
5
+ use rayon:: iter:: ParallelIterator ;
5
6
use std:: collections:: HashMap ;
6
7
use std:: fs:: { self } ;
8
+ use std:: sync:: Mutex ;
7
9
8
10
pub ( crate ) struct RegistryList ;
9
11
10
12
impl List for RegistryList {
11
13
const NAME : & ' static str = "registry" ;
12
14
13
15
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 ( ) ) ;
16
17
18
+ debug ! ( "updating git index" ) ;
17
19
fs:: create_dir_all ( & * WORK_DIR ) ?;
18
20
let mut index = GitIndex :: with_path (
19
21
WORK_DIR . join ( "crates.io-index" ) ,
20
22
"https://github.com/rust-lang/crates.io-index" ,
21
23
) ?;
22
24
index. update ( ) ?;
25
+ debug ! ( "collecting crate information" ) ;
23
26
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 ( ) ;
45
55
46
56
// Ensure the list is sorted by popularity
57
+ let counts = counts. lock ( ) . unwrap ( ) ;
47
58
list. sort_by ( |a, b| {
48
59
if let ( Crate :: Registry ( ref a) , Crate :: Registry ( ref b) ) = ( a, b) {
49
60
let count_a = counts. get ( & a. name ) . cloned ( ) . unwrap_or ( 0 ) ;
0 commit comments