Skip to content

Commit 5224627

Browse files
Merge pull request #776 from ehuss/parallel-crates
Process crates in parallel in prepare-local
2 parents 1a8ed56 + a1e2984 commit 5224627

File tree

3 files changed

+38
-23
lines changed

3 files changed

+38
-23
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ clap = { version = "4", features = ["derive"] }
2424
crates-index = { version = "2.2.0", default-features = false, features = [
2525
"git-performance",
2626
"git-https",
27+
"parallel",
2728
] }
2829
crossbeam-channel = "0.5"
2930
csv = "1.0.2"
@@ -45,6 +46,7 @@ percent-encoding = "2.1.0"
4546
prometheus = "0.13.3"
4647
r2d2 = "0.8.2"
4748
rand = "0.8"
49+
rayon = "1.10"
4850
regex = "1.0"
4951
remove_dir_all = "0.7"
5052
reqwest = { version = "0.11", features = ["blocking", "json"] }

src/crates/sources/registry.rs

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,48 +2,59 @@ use crate::crates::{lists::List, Crate};
22
use crate::dirs::WORK_DIR;
33
use crate::prelude::*;
44
use crates_index::GitIndex;
5+
use rayon::iter::ParallelIterator;
56
use std::collections::HashMap;
67
use std::fs::{self};
8+
use std::sync::Mutex;
79

810
pub(crate) struct RegistryList;
911

1012
impl 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

Comments
 (0)