Skip to content

Commit b0ddb5f

Browse files
committed
Improve performance
1 parent e9170cb commit b0ddb5f

38 files changed

+3814
-2563
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,14 @@ keywords = ["dependency", "pubgrub", "semver", "solver", "version"]
2020
categories = ["algorithms"]
2121
include = ["Cargo.toml", "LICENSE", "README.md", "src/**", "tests/**", "examples/**", "benches/**"]
2222

23-
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
24-
2523
[dependencies]
2624
indexmap = "2.6.0"
2725
# for debug logs in tests
2826
log = "0.4.22"
2927
priority-queue = "2.1.1"
3028
rustc-hash = ">=1.0.0, <3.0.0"
3129
serde = { version = "1.0", features = ["derive"], optional = true }
30+
smallvec = { version = "1.13.2", features = ["union"] }
3231
thiserror = "2.0"
3332
version-ranges = { version = "0.1.0", path = "version-ranges" }
3433

README.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,6 @@ So, because root depends on both menu >=1.0.0 and intl >=5.0.0,
2929
```
3030

3131
This pubgrub crate provides a Rust implementation of PubGrub.
32-
It is generic and works for any type of dependency system
33-
as long as packages (P) and versions (V) implement
34-
the provided `Package` and `Version` traits.
35-
3632

3733
## Using the pubgrub crate
3834

benches/backtracking.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ fn backtracking_singletons(c: &mut Criterion, package_count: u32, version_count:
2626

2727
c.bench_function("backtracking_singletons", |b| {
2828
b.iter(|| {
29-
let _ = pubgrub::resolve(&dependency_provider, 0u32, 0u32);
29+
let _ = dependency_provider.resolve(0u32, 0u32);
3030
})
3131
});
3232
}
@@ -59,7 +59,7 @@ fn backtracking_disjoint_versions(c: &mut Criterion, package_count: u32, version
5959

6060
c.bench_function("backtracking_disjoint_versions", |b| {
6161
b.iter(|| {
62-
let _ = pubgrub::resolve(&dependency_provider, 0u32, 0u32);
62+
let _ = dependency_provider.resolve(0u32, 0u32);
6363
})
6464
});
6565
}
@@ -83,7 +83,7 @@ fn backtracking_ranges(c: &mut Criterion, package_count: u32, version_count: u32
8383

8484
c.bench_function("backtracking_ranges", |b| {
8585
b.iter(|| {
86-
let _ = pubgrub::resolve(&dependency_provider, 0u32, 0u32);
86+
let _ = dependency_provider.resolve(0u32, 0u32);
8787
})
8888
});
8989
}

benches/large_case.rs

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,38 @@
11
// SPDX-License-Identifier: MPL-2.0
2-
2+
use std::fmt::{Debug, Display};
3+
use std::hash::Hash;
34
use std::time::Duration;
45

56
use criterion::*;
7+
use pubgrub::{Map, OfflineDependencyProvider, Range, VersionRanges};
68
use serde::de::Deserialize;
79

8-
use pubgrub::{resolve, OfflineDependencyProvider, Package, Range, SemanticVersion, VersionSet};
9-
10-
fn bench<'a, P: Package + Deserialize<'a>, VS: VersionSet + Deserialize<'a>>(
10+
fn bench<
11+
'a,
12+
P: Debug + Display + Clone + Eq + Hash + Deserialize<'a>,
13+
R: VersionRanges + Deserialize<'a>,
14+
>(
1115
b: &mut Bencher,
1216
case: &'a str,
1317
) where
14-
<VS as VersionSet>::V: Deserialize<'a>,
18+
R::V: Deserialize<'a>,
1519
{
16-
let dependency_provider: OfflineDependencyProvider<P, VS> = ron::de::from_str(case).unwrap();
20+
let mut dependency_provider: OfflineDependencyProvider<P, R> = ron::de::from_str(case).unwrap();
21+
22+
let dependencies = dependency_provider
23+
.packages()
24+
.map(|p| {
25+
(
26+
p.clone(),
27+
dependency_provider.versions(p).unwrap().cloned().collect(),
28+
)
29+
})
30+
.collect::<Map<_, Vec<_>>>();
1731

1832
b.iter(|| {
19-
for p in dependency_provider.packages() {
20-
for n in dependency_provider.versions(p).unwrap() {
21-
let _ = resolve(&dependency_provider, p.clone(), n.clone());
33+
for (p, versions) in &dependencies {
34+
for v in versions {
35+
let _ = dependency_provider.resolve(p.clone(), v.clone());
2236
}
2337
}
2438
});
@@ -32,14 +46,10 @@ fn bench_nested(c: &mut Criterion) {
3246
let case = case.unwrap().path();
3347
let name = case.file_name().unwrap().to_string_lossy();
3448
let data = std::fs::read_to_string(&case).unwrap();
35-
if name.ends_with("u16_NumberVersion.ron") || name.ends_with("u16_u32.ron") {
49+
if name.ends_with("u16_NumberVersion.ron") {
3650
group.bench_function(name, |b| {
3751
bench::<u16, Range<u32>>(b, &data);
3852
});
39-
} else if name.ends_with("str_SemanticVersion.ron") {
40-
group.bench_function(name, |b| {
41-
bench::<&str, Range<SemanticVersion>>(b, &data);
42-
});
4353
}
4454
}
4555

benches/sudoku.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
//! Uses `Arc<usize>` for being closer to real versions.
44
// SPDX-License-Identifier: MPL-2.0
55

6-
use pubgrub::{resolve, OfflineDependencyProvider, Range};
76
use std::fmt;
87
use std::sync::Arc;
9-
use version_ranges::Ranges;
108

119
use criterion::*;
10+
use pubgrub::{OfflineDependencyProvider, Range};
11+
use version_ranges::Ranges;
1212

1313
/// The size of a box in the board.
1414
const BOARD_BASE: usize = 3;
@@ -122,7 +122,7 @@ fn solve(c: &mut Criterion, board: Vec<(SudokuPackage, Ranges<Arc<usize>>)>, cas
122122
dependency_provider.add_dependencies(SudokuPackage::Root, Arc::new(1usize), board);
123123
c.bench_function(case, |b| {
124124
b.iter(|| {
125-
let _ = resolve(&dependency_provider, SudokuPackage::Root, Arc::new(1usize));
125+
let _ = dependency_provider.resolve(SudokuPackage::Root, Arc::new(1usize));
126126
})
127127
});
128128
}

examples/branching_error_reporting.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: MPL-2.0
22

33
use pubgrub::{
4-
resolve, DefaultStringReporter, OfflineDependencyProvider, PubGrubError, Ranges, Reporter,
4+
DefaultStringReporter, OfflineDependencyProvider, PubGrubError, Ranges, Reporter,
55
SemanticVersion,
66
};
77

@@ -10,15 +10,16 @@ type SemVS = Ranges<SemanticVersion>;
1010
// https://github.com/dart-lang/pub/blob/master/doc/solver.md#branching-error-reporting
1111
fn main() {
1212
let mut dependency_provider = OfflineDependencyProvider::<&str, SemVS>::new();
13+
1314
#[rustfmt::skip]
1415
// root 1.0.0 depends on foo ^1.0.0
15-
dependency_provider.add_dependencies(
16+
dependency_provider.add_dependencies(
1617
"root", (1, 0, 0),
1718
[("foo", Ranges::from_range_bounds((1, 0, 0)..(2, 0, 0)))],
1819
);
1920
#[rustfmt::skip]
2021
// foo 1.0.0 depends on a ^1.0.0 and b ^1.0.0
21-
dependency_provider.add_dependencies(
22+
dependency_provider.add_dependencies(
2223
"foo", (1, 0, 0),
2324
[
2425
("a", Ranges::from_range_bounds((1, 0, 0)..(2, 0, 0))),
@@ -27,7 +28,7 @@ fn main() {
2728
);
2829
#[rustfmt::skip]
2930
// foo 1.1.0 depends on x ^1.0.0 and y ^1.0.0
30-
dependency_provider.add_dependencies(
31+
dependency_provider.add_dependencies(
3132
"foo", (1, 1, 0),
3233
[
3334
("x", Ranges::from_range_bounds((1, 0, 0)..(2, 0, 0))),
@@ -36,7 +37,7 @@ fn main() {
3637
);
3738
#[rustfmt::skip]
3839
// a 1.0.0 depends on b ^2.0.0
39-
dependency_provider.add_dependencies(
40+
dependency_provider.add_dependencies(
4041
"a", (1, 0, 0),
4142
[("b", Ranges::from_range_bounds((2, 0, 0)..(3, 0, 0)))],
4243
);
@@ -45,7 +46,7 @@ fn main() {
4546
dependency_provider.add_dependencies("b", (2, 0, 0), []);
4647
#[rustfmt::skip]
4748
// x 1.0.0 depends on y ^2.0.0.
48-
dependency_provider.add_dependencies(
49+
dependency_provider.add_dependencies(
4950
"x", (1, 0, 0),
5051
[("y", Ranges::from_range_bounds((2, 0, 0)..(3, 0, 0)))],
5152
);
@@ -54,11 +55,14 @@ fn main() {
5455
dependency_provider.add_dependencies("y", (2, 0, 0), []);
5556

5657
// Run the algorithm.
57-
match resolve(&dependency_provider, "root", (1, 0, 0)) {
58+
match dependency_provider.resolve("root", (1, 0, 0)) {
5859
Ok(sol) => println!("{:?}", sol),
59-
Err(PubGrubError::NoSolution(mut derivation_tree)) => {
60-
derivation_tree.collapse_no_versions();
61-
eprintln!("{}", DefaultStringReporter::report(&derivation_tree));
60+
Err(PubGrubError::NoSolution(mut error)) => {
61+
error.derivation_tree.collapse_no_versions();
62+
eprintln!(
63+
"{}",
64+
DefaultStringReporter::report(&error, &dependency_provider)
65+
);
6266
std::process::exit(1);
6367
}
6468
Err(err) => panic!("{:?}", err),

0 commit comments

Comments
 (0)