Skip to content

Commit

Permalink
Use u64 for version set type
Browse files Browse the repository at this point in the history
  • Loading branch information
x-hgg-x committed Nov 20, 2024
1 parent fa26eb3 commit 37f165a
Show file tree
Hide file tree
Showing 29 changed files with 2,396 additions and 1,296 deletions.
6 changes: 3 additions & 3 deletions benches/backtracking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ fn backtracking_singletons(c: &mut Criterion, package_count: u32, version_count:

c.bench_function("backtracking_singletons", |b| {
b.iter(|| {
let _ = pubgrub::resolve(&mut dependency_provider, 0u32, 0u32);
let _ = dependency_provider.resolve(0u32, 0u32);
})
});
}
Expand Down Expand Up @@ -59,7 +59,7 @@ fn backtracking_disjoint_versions(c: &mut Criterion, package_count: u32, version

c.bench_function("backtracking_disjoint_versions", |b| {
b.iter(|| {
let _ = pubgrub::resolve(&mut dependency_provider, 0u32, 0u32);
let _ = dependency_provider.resolve(0u32, 0u32);
})
});
}
Expand All @@ -83,7 +83,7 @@ fn backtracking_ranges(c: &mut Criterion, package_count: u32, version_count: u32

c.bench_function("backtracking_ranges", |b| {
b.iter(|| {
let _ = pubgrub::resolve(&mut dependency_provider, 0u32, 0u32);
let _ = dependency_provider.resolve(0u32, 0u32);
})
});
}
Expand Down
19 changes: 7 additions & 12 deletions benches/large_case.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,19 @@ use std::time::Duration;
use criterion::*;
use serde::de::Deserialize;

use pubgrub::{resolve, Map, OfflineDependencyProvider, Range, SemanticVersion, VersionSet};
use pubgrub::{Map, OfflineDependencyProvider, Range, VersionRanges};

fn bench<
'a,
P: Debug + Display + Clone + Eq + Hash + Deserialize<'a>,
VS: VersionSet + Deserialize<'a>,
R: VersionRanges + Deserialize<'a>,
>(
b: &mut Bencher,
case: &'a str,
) where
<VS as VersionSet>::V: Deserialize<'a>,
R::V: Deserialize<'a>,
{
let mut dependency_provider: OfflineDependencyProvider<P, VS> =
ron::de::from_str(case).unwrap();
let mut dependency_provider: OfflineDependencyProvider<P, R> = ron::de::from_str(case).unwrap();

let dependencies = dependency_provider
.packages()
Expand All @@ -34,8 +33,8 @@ fn bench<

b.iter(|| {
for (p, versions) in &dependencies {
for n in versions {
let _ = resolve(&mut dependency_provider, p.clone(), n.clone());
for v in versions {
let _ = dependency_provider.resolve(p.clone(), v.clone());
}
}
});
Expand All @@ -49,14 +48,10 @@ fn bench_nested(c: &mut Criterion) {
let case = case.unwrap().path();
let name = case.file_name().unwrap().to_string_lossy();
let data = std::fs::read_to_string(&case).unwrap();
if name.ends_with("u16_NumberVersion.ron") || name.ends_with("u16_u32.ron") {
if name.ends_with("u16_NumberVersion.ron") {
group.bench_function(name, |b| {
bench::<u16, Range<u32>>(b, &data);
});
} else if name.ends_with("str_SemanticVersion.ron") {
group.bench_function(name, |b| {
bench::<&str, Range<SemanticVersion>>(b, &data);
});
}
}

Expand Down
16 changes: 7 additions & 9 deletions benches/sudoku.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
// SPDX-License-Identifier: MPL-2.0

use pubgrub::{
resolve, DefaultStringReporter, OfflineDependencyProvider, PubGrubError, Range, Reporter,
SelectedDependencies,
DefaultStringReporter, Map, OfflineDependencyProvider, PubGrubError, Range, Reporter,
};
use std::fmt;
use std::sync::Arc;
Expand Down Expand Up @@ -119,19 +118,18 @@ fn encode_constraints(
}
}

fn solve(board: Vec<(SudokuPackage, Ranges<Arc<usize>>)>) -> SelectedDependencies<DP> {
fn solve(board: Vec<(SudokuPackage, Ranges<Arc<usize>>)>) -> Map<SudokuPackage, Arc<usize>> {
let mut dependency_provider = DP::new();
encode_constraints(&mut dependency_provider);
dependency_provider.add_dependencies(SudokuPackage::Root, Arc::new(1usize), board);
match resolve(
&mut dependency_provider,
SudokuPackage::Root,
Arc::new(1usize),
) {
match dependency_provider.resolve(SudokuPackage::Root, Arc::new(1usize)) {
Ok(sol) => sol,
Err(PubGrubError::NoSolution(mut error)) => {
error.derivation_tree.collapse_no_versions();
eprintln!("{}", DefaultStringReporter::report(&error));
eprintln!(
"{}",
DefaultStringReporter::report(&error, &dependency_provider)
);
std::process::exit(1);
}
Err(err) => panic!("{:?}", err),
Expand Down
20 changes: 12 additions & 8 deletions examples/branching_error_reporting.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MPL-2.0

use pubgrub::{
resolve, DefaultStringReporter, OfflineDependencyProvider, PubGrubError, Ranges, Reporter,
DefaultStringReporter, OfflineDependencyProvider, PubGrubError, Ranges, Reporter,
SemanticVersion,
};

Expand All @@ -10,15 +10,16 @@ type SemVS = Ranges<SemanticVersion>;
// https://github.com/dart-lang/pub/blob/master/doc/solver.md#branching-error-reporting
fn main() {
let mut dependency_provider = OfflineDependencyProvider::<&str, SemVS>::new();

#[rustfmt::skip]
// root 1.0.0 depends on foo ^1.0.0
dependency_provider.add_dependencies(
dependency_provider.add_dependencies(
"root", (1, 0, 0),
[("foo", Ranges::from_range_bounds((1, 0, 0)..(2, 0, 0)))],
);
#[rustfmt::skip]
// foo 1.0.0 depends on a ^1.0.0 and b ^1.0.0
dependency_provider.add_dependencies(
dependency_provider.add_dependencies(
"foo", (1, 0, 0),
[
("a", Ranges::from_range_bounds((1, 0, 0)..(2, 0, 0))),
Expand All @@ -27,7 +28,7 @@ fn main() {
);
#[rustfmt::skip]
// foo 1.1.0 depends on x ^1.0.0 and y ^1.0.0
dependency_provider.add_dependencies(
dependency_provider.add_dependencies(
"foo", (1, 1, 0),
[
("x", Ranges::from_range_bounds((1, 0, 0)..(2, 0, 0))),
Expand All @@ -36,7 +37,7 @@ fn main() {
);
#[rustfmt::skip]
// a 1.0.0 depends on b ^2.0.0
dependency_provider.add_dependencies(
dependency_provider.add_dependencies(
"a", (1, 0, 0),
[("b", Ranges::from_range_bounds((2, 0, 0)..(3, 0, 0)))],
);
Expand All @@ -45,7 +46,7 @@ fn main() {
dependency_provider.add_dependencies("b", (2, 0, 0), []);
#[rustfmt::skip]
// x 1.0.0 depends on y ^2.0.0.
dependency_provider.add_dependencies(
dependency_provider.add_dependencies(
"x", (1, 0, 0),
[("y", Ranges::from_range_bounds((2, 0, 0)..(3, 0, 0)))],
);
Expand All @@ -54,11 +55,14 @@ fn main() {
dependency_provider.add_dependencies("y", (2, 0, 0), []);

// Run the algorithm.
match resolve(&mut dependency_provider, "root", (1, 0, 0)) {
match dependency_provider.resolve("root", (1, 0, 0)) {
Ok(sol) => println!("{:?}", sol),
Err(PubGrubError::NoSolution(mut error)) => {
error.derivation_tree.collapse_no_versions();
eprintln!("{}", DefaultStringReporter::report(&error));
eprintln!(
"{}",
DefaultStringReporter::report(&error, &dependency_provider)
);
std::process::exit(1);
}
Err(err) => panic!("{:?}", err),
Expand Down
99 changes: 78 additions & 21 deletions examples/caching_dependency_provider.rs
Original file line number Diff line number Diff line change
@@ -1,65 +1,106 @@
// SPDX-License-Identifier: MPL-2.0

use std::cell::RefCell;
use std::collections::BTreeMap;
use std::fmt::{Debug, Display};
use std::hash::Hash;

use pubgrub::{
resolve, Dependencies, DependencyConstraints, DependencyProvider, Map,
OfflineDependencyProvider, PackageArena, PackageId, Ranges,
OfflineDependencyProvider, PackageArena, PackageId, PackageVersionWrapper, PubGrubError,
Ranges, SelectedDependencies, VersionIndex, VersionRanges, VersionSet,
};

type NumVS = Ranges<u32>;
type CachedDeps<V, VS> = RefCell<Map<PackageId, BTreeMap<V, DependencyConstraints<VS>>>>;

trait RemoteProvider: DependencyProvider<P = PackageVersionWrapper<Self::Pkg>> {
type Pkg: Debug + Display + Clone + Eq + Hash;
type R: VersionRanges;

fn resolve_parameters(
&self,
p: Self::Pkg,
v: impl Into<<Self::R as VersionRanges>::V>,
) -> Option<(PackageVersionWrapper<Self::Pkg>, VersionIndex)>;
}

impl<P: Debug + Display + Clone + Eq + Hash, R: VersionRanges> RemoteProvider
for OfflineDependencyProvider<P, R>
{
type Pkg = P;
type R = R;

fn resolve_parameters(
&self,
p: P,
v: impl Into<<Self::R as VersionRanges>::V>,
) -> Option<(PackageVersionWrapper<P>, VersionIndex)> {
self.resolve_parameters(p, v)
}
}

// An example implementing caching dependency provider that will
// store queried dependencies in memory and check them before querying more from remote.
struct CachingDependencyProvider<DP: DependencyProvider>
struct CachingDependencyProvider<DP: RemoteProvider<R = R>, R: VersionRanges>
where
DP::P: Debug + Display + Clone + Eq + Hash,
{
remote_dependencies: DP,
cached_dependencies: CachedDeps<DP::V, DP::VS>,
cached_dependencies: RefCell<Map<PackageId, Map<VersionIndex, DependencyConstraints>>>,
}

impl<DP: DependencyProvider> CachingDependencyProvider<DP>
impl<DP: RemoteProvider<R = R>, R: VersionRanges> CachingDependencyProvider<DP, R>
where
DP::P: Debug + Display + Clone + Eq + Hash,
{
pub fn new(remote_dependencies_provider: DP) -> Self {
fn new(remote_dependencies_provider: DP) -> Self {
CachingDependencyProvider {
remote_dependencies: remote_dependencies_provider,
cached_dependencies: Default::default(),
}
}

fn resolve(
&mut self,
p: <DP as RemoteProvider>::Pkg,
v: impl Into<R::V>,
) -> Result<SelectedDependencies<Self>, PubGrubError<Self>> {
let Some((p, v)) = self.remote_dependencies.resolve_parameters(p, v) else {
return Err(PubGrubError::NoRoot);
};
resolve(self, p, v)
}
}

impl<DP: DependencyProvider<M = &'static str>> DependencyProvider for CachingDependencyProvider<DP>
impl<DP: RemoteProvider<R = R>, R: VersionRanges> DependencyProvider
for CachingDependencyProvider<DP, R>
where
DP::P: Debug + Display + Clone + Eq + Hash,
R::V: Clone,
{
// Cache dependencies if they were already queried
fn get_dependencies(
&mut self,
package_id: PackageId,
version: &DP::V,
version_index: VersionIndex,
package_store: &mut PackageArena<Self::P>,
) -> Result<Dependencies<DP::VS, DP::M>, DP::Err> {
) -> Result<Dependencies<DP::M>, DP::Err> {
let mut cache = self.cached_dependencies.borrow_mut();
if let Some(deps) = cache.get(&package_id).and_then(|vmap| vmap.get(version)) {
if let Some(deps) = cache
.get(&package_id)
.and_then(|vmap| vmap.get(&version_index))
{
return Ok(Dependencies::Available(deps.clone()));
}

match self
.remote_dependencies
.get_dependencies(package_id, version, package_store)
.get_dependencies(package_id, version_index, package_store)
{
Ok(Dependencies::Available(deps)) => {
cache
.entry(package_id)
.or_default()
.insert(version.clone(), deps.clone());
.insert(version_index, deps.clone());
Ok(Dependencies::Available(deps))
}

Expand All @@ -71,31 +112,47 @@ where
fn choose_version(
&mut self,
package_id: PackageId,
ranges: &DP::VS,
set: VersionSet,
package_store: &PackageArena<Self::P>,
) -> Result<Option<DP::V>, DP::Err> {
) -> Result<Option<VersionIndex>, DP::Err> {
self.remote_dependencies
.choose_version(package_id, ranges, package_store)
.choose_version(package_id, set, package_store)
}

type Priority = DP::Priority;

fn prioritize(
&mut self,
package_id: PackageId,
ranges: &DP::VS,
set: VersionSet,
package_store: &PackageArena<Self::P>,
) -> Self::Priority {
self.remote_dependencies
.prioritize(package_id, ranges, package_store)
.prioritize(package_id, set, package_store)
}

type Err = DP::Err;

type P = DP::P;
type V = DP::V;
type VS = DP::VS;
type M = DP::M;

fn package_version_display<'a>(
&'a self,
package: &'a Self::P,
version_index: VersionIndex,
) -> impl Display + 'a {
self.remote_dependencies
.package_version_display(package, version_index)
}

fn package_version_set_display<'a>(
&'a self,
package: &'a Self::P,
version_set: VersionSet,
) -> impl Display + 'a {
self.remote_dependencies
.package_version_set_display(package, version_set)
}
}

fn main() {
Expand All @@ -108,6 +165,6 @@ fn main() {
let mut caching_dependencies_provider =
CachingDependencyProvider::new(remote_dependencies_provider);

let solution = resolve(&mut caching_dependencies_provider, "root", 1u32);
let solution = caching_dependencies_provider.resolve("root", 1u32);
println!("Solution: {:?}", solution);
}
6 changes: 3 additions & 3 deletions examples/doc_interface.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MPL-2.0

use pubgrub::{resolve, OfflineDependencyProvider, Ranges};
use pubgrub::{OfflineDependencyProvider, Ranges};

type NumVS = Ranges<u32>;

Expand All @@ -19,6 +19,6 @@ fn main() {
dependency_provider.add_dependencies("icons", 1u32, []);

// Run the algorithm.
let solution = resolve(&mut dependency_provider, "root", 1u32);
println!("Solution: {:?}", solution);
let solution = dependency_provider.resolve("root", 1u32).unwrap();
println!("Solution: {solution:?}");
}
Loading

0 comments on commit 37f165a

Please sign in to comment.