Skip to content

Commit 6129182

Browse files
committed
Use an arena for packages
1 parent 97cc341 commit 6129182

24 files changed

+1140
-774
lines changed

benches/large_case.rs

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

46
use criterion::*;
57
use serde::de::Deserialize;
68

7-
use pubgrub::{resolve, OfflineDependencyProvider, Package, Range, SemanticVersion, VersionSet};
9+
use pubgrub::{resolve, Map, OfflineDependencyProvider, Range, SemanticVersion, VersionSet};
810

9-
fn bench<'a, P: Package + Deserialize<'a>, VS: VersionSet + Deserialize<'a>>(
11+
fn bench<
12+
'a,
13+
P: Debug + Display + Clone + Eq + Hash + Deserialize<'a>,
14+
VS: VersionSet + Deserialize<'a>,
15+
>(
1016
b: &mut Bencher,
1117
case: &'a str,
1218
) where
1319
<VS as VersionSet>::V: Deserialize<'a>,
1420
{
15-
let dependency_provider: OfflineDependencyProvider<P, VS> = ron::de::from_str(case).unwrap();
21+
let mut dependency_provider: OfflineDependencyProvider<P, VS> =
22+
ron::de::from_str(case).unwrap();
23+
24+
let dependencies = dependency_provider
25+
.packages()
26+
.map(|p| {
27+
(
28+
p.clone(),
29+
dependency_provider.versions(p).unwrap().cloned().collect(),
30+
)
31+
})
32+
.collect::<Map<_, Vec<_>>>();
1633

1734
b.iter(|| {
18-
for p in dependency_provider.packages() {
19-
for n in dependency_provider.versions(p).unwrap() {
20-
let _ = resolve(&dependency_provider, p.clone(), n.clone());
35+
for (p, versions) in &dependencies {
36+
for n in versions {
37+
let _ = resolve(&mut dependency_provider, p.clone(), n.clone());
2138
}
2239
}
2340
});

benches/sudoku.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,11 @@ fn solve(board: Vec<(SudokuPackage, Ranges<u8>)>) -> SelectedDependencies<DP> {
121121
let mut dependency_provider = DP::new();
122122
encode_constraints(&mut dependency_provider);
123123
dependency_provider.add_dependencies(SudokuPackage::Root, 1, board);
124-
match resolve(&dependency_provider, SudokuPackage::Root, 1) {
124+
match resolve(&mut dependency_provider, SudokuPackage::Root, 1) {
125125
Ok(sol) => sol,
126-
Err(PubGrubError::NoSolution(mut derivation_tree)) => {
127-
derivation_tree.collapse_no_versions();
128-
eprintln!("{}", DefaultStringReporter::report(&derivation_tree));
126+
Err(PubGrubError::NoSolution(mut error)) => {
127+
error.derivation_tree.collapse_no_versions();
128+
eprintln!("{}", DefaultStringReporter::report(&error));
129129
std::process::exit(1);
130130
}
131131
Err(err) => panic!("{:?}", err),

examples/branching_error_reporting.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,11 @@ fn main() {
5454
dependency_provider.add_dependencies("y", (2, 0, 0), []);
5555

5656
// Run the algorithm.
57-
match resolve(&dependency_provider, "root", (1, 0, 0)) {
57+
match resolve(&mut dependency_provider, "root", (1, 0, 0)) {
5858
Ok(sol) => println!("{:?}", sol),
59-
Err(PubGrubError::NoSolution(mut derivation_tree)) => {
60-
derivation_tree.collapse_no_versions();
61-
eprintln!("{}", DefaultStringReporter::report(&derivation_tree));
59+
Err(PubGrubError::NoSolution(mut error)) => {
60+
error.derivation_tree.collapse_no_versions();
61+
eprintln!("{}", DefaultStringReporter::report(&error));
6262
std::process::exit(1);
6363
}
6464
Err(err) => panic!("{:?}", err),
Lines changed: 62 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,93 @@
11
// SPDX-License-Identifier: MPL-2.0
22

33
use std::cell::RefCell;
4+
use std::collections::BTreeMap;
5+
use std::fmt::{Debug, Display};
6+
use std::hash::Hash;
47

5-
use pubgrub::{resolve, Dependencies, DependencyProvider, OfflineDependencyProvider, Ranges};
8+
use pubgrub::{
9+
resolve, Dependencies, DependencyConstraints, DependencyProvider, Map,
10+
OfflineDependencyProvider, Package, PackageArena, Ranges,
11+
};
612

713
type NumVS = Ranges<u32>;
14+
type CachedDeps<V, VS> = RefCell<Map<Package, BTreeMap<V, DependencyConstraints<VS>>>>;
815

916
// An example implementing caching dependency provider that will
1017
// store queried dependencies in memory and check them before querying more from remote.
11-
struct CachingDependencyProvider<DP: DependencyProvider> {
18+
struct CachingDependencyProvider<DP: DependencyProvider>
19+
where
20+
DP::P: Debug + Display + Clone + Eq + Hash,
21+
{
1222
remote_dependencies: DP,
13-
cached_dependencies: RefCell<OfflineDependencyProvider<DP::P, DP::VS>>,
23+
cached_dependencies: CachedDeps<DP::V, DP::VS>,
1424
}
1525

16-
impl<DP: DependencyProvider> CachingDependencyProvider<DP> {
26+
impl<DP: DependencyProvider> CachingDependencyProvider<DP>
27+
where
28+
DP::P: Debug + Display + Clone + Eq + Hash,
29+
{
1730
pub fn new(remote_dependencies_provider: DP) -> Self {
1831
CachingDependencyProvider {
1932
remote_dependencies: remote_dependencies_provider,
20-
cached_dependencies: RefCell::new(OfflineDependencyProvider::new()),
33+
cached_dependencies: Default::default(),
2134
}
2235
}
2336
}
2437

25-
impl<DP: DependencyProvider<M = String>> DependencyProvider for CachingDependencyProvider<DP> {
26-
// Caches dependencies if they were already queried
38+
impl<DP: DependencyProvider<M = &'static str>> DependencyProvider for CachingDependencyProvider<DP>
39+
where
40+
DP::P: Debug + Display + Clone + Eq + Hash,
41+
{
42+
// Cache dependencies if they were already queried
2743
fn get_dependencies(
28-
&self,
29-
package: &DP::P,
44+
&mut self,
45+
package: Package,
3046
version: &DP::V,
31-
) -> Result<Dependencies<DP::P, DP::VS, DP::M>, DP::Err> {
47+
package_store: &mut PackageArena<Self::P>,
48+
) -> Result<Dependencies<DP::VS, DP::M>, DP::Err> {
3249
let mut cache = self.cached_dependencies.borrow_mut();
33-
match cache.get_dependencies(package, version) {
34-
Ok(Dependencies::Unavailable(_)) => {
35-
let dependencies = self.remote_dependencies.get_dependencies(package, version);
36-
match dependencies {
37-
Ok(Dependencies::Available(dependencies)) => {
38-
cache.add_dependencies(
39-
package.clone(),
40-
version.clone(),
41-
dependencies.clone(),
42-
);
43-
Ok(Dependencies::Available(dependencies))
44-
}
45-
Ok(Dependencies::Unavailable(reason)) => Ok(Dependencies::Unavailable(reason)),
46-
error @ Err(_) => error,
47-
}
50+
if let Some(deps) = cache.get(&package).and_then(|vmap| vmap.get(version)) {
51+
return Ok(Dependencies::Available(deps.clone()));
52+
}
53+
54+
match self
55+
.remote_dependencies
56+
.get_dependencies(package, version, package_store)
57+
{
58+
Ok(Dependencies::Available(deps)) => {
59+
cache
60+
.entry(package)
61+
.or_default()
62+
.insert(version.clone(), deps.clone());
63+
Ok(Dependencies::Available(deps))
4864
}
49-
Ok(dependencies) => Ok(dependencies),
50-
Err(_) => unreachable!(),
65+
66+
Ok(Dependencies::Unavailable(reason)) => Ok(Dependencies::Unavailable(reason)),
67+
error @ Err(_) => error,
5168
}
5269
}
5370

54-
fn choose_version(&self, package: &DP::P, ranges: &DP::VS) -> Result<Option<DP::V>, DP::Err> {
55-
self.remote_dependencies.choose_version(package, ranges)
71+
fn choose_version(
72+
&mut self,
73+
package: Package,
74+
ranges: &DP::VS,
75+
package_store: &PackageArena<Self::P>,
76+
) -> Result<Option<DP::V>, DP::Err> {
77+
self.remote_dependencies
78+
.choose_version(package, ranges, package_store)
5679
}
5780

5881
type Priority = DP::Priority;
5982

60-
fn prioritize(&self, package: &DP::P, ranges: &DP::VS) -> Self::Priority {
61-
self.remote_dependencies.prioritize(package, ranges)
83+
fn prioritize(
84+
&mut self,
85+
package: Package,
86+
ranges: &DP::VS,
87+
package_store: &PackageArena<Self::P>,
88+
) -> Self::Priority {
89+
self.remote_dependencies
90+
.prioritize(package, ranges, package_store)
6291
}
6392

6493
type Err = DP::Err;
@@ -76,9 +105,9 @@ fn main() {
76105
// Add dependencies as needed. Here only root package is added.
77106
remote_dependencies_provider.add_dependencies("root", 1u32, Vec::new());
78107

79-
let caching_dependencies_provider =
108+
let mut caching_dependencies_provider =
80109
CachingDependencyProvider::new(remote_dependencies_provider);
81110

82-
let solution = resolve(&caching_dependencies_provider, "root", 1u32);
111+
let solution = resolve(&mut caching_dependencies_provider, "root", 1u32);
83112
println!("Solution: {:?}", solution);
84113
}

examples/doc_interface.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,6 @@ fn main() {
1919
dependency_provider.add_dependencies("icons", 1u32, []);
2020

2121
// Run the algorithm.
22-
let solution = resolve(&dependency_provider, "root", 1u32);
22+
let solution = resolve(&mut dependency_provider, "root", 1u32);
2323
println!("Solution: {:?}", solution);
2424
}

examples/doc_interface_error.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,11 @@ fn main() {
7171
dependency_provider.add_dependencies("intl", (5, 0, 0), []);
7272

7373
// Run the algorithm.
74-
match resolve(&dependency_provider, "root", (1, 0, 0)) {
74+
match resolve(&mut dependency_provider, "root", (1, 0, 0)) {
7575
Ok(sol) => println!("{:?}", sol),
76-
Err(PubGrubError::NoSolution(mut derivation_tree)) => {
77-
derivation_tree.collapse_no_versions();
78-
eprintln!("{}", DefaultStringReporter::report(&derivation_tree));
76+
Err(PubGrubError::NoSolution(mut error)) => {
77+
error.derivation_tree.collapse_no_versions();
78+
eprintln!("{}", DefaultStringReporter::report(&error));
7979
}
8080
Err(err) => panic!("{:?}", err),
8181
};

examples/doc_interface_semantic.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,11 @@ fn main() {
6262
dependency_provider.add_dependencies("icons", (2, 0, 0), []);
6363

6464
// Run the algorithm.
65-
match resolve(&dependency_provider, "root", (1, 0, 0)) {
65+
match resolve(&mut dependency_provider, "root", (1, 0, 0)) {
6666
Ok(sol) => println!("{:?}", sol),
67-
Err(PubGrubError::NoSolution(mut derivation_tree)) => {
68-
derivation_tree.collapse_no_versions();
69-
eprintln!("{}", DefaultStringReporter::report(&derivation_tree));
67+
Err(PubGrubError::NoSolution(mut error)) => {
68+
error.derivation_tree.collapse_no_versions();
69+
eprintln!("{}", DefaultStringReporter::report(&error));
7070
}
7171
Err(err) => panic!("{:?}", err),
7272
};

examples/linear_error_reporting.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ fn main() {
3636
dependency_provider.add_dependencies("baz", (3, 0, 0), []);
3737

3838
// Run the algorithm.
39-
match resolve(&dependency_provider, "root", (1, 0, 0)) {
39+
match resolve(&mut dependency_provider, "root", (1, 0, 0)) {
4040
Ok(sol) => println!("{:?}", sol),
41-
Err(PubGrubError::NoSolution(mut derivation_tree)) => {
42-
derivation_tree.collapse_no_versions();
43-
eprintln!("{}", DefaultStringReporter::report(&derivation_tree));
41+
Err(PubGrubError::NoSolution(mut error)) => {
42+
error.derivation_tree.collapse_no_versions();
43+
eprintln!("{}", DefaultStringReporter::report(&error));
4444
std::process::exit(1);
4545
}
4646
Err(err) => panic!("{:?}", err),

0 commit comments

Comments
 (0)