Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: upgrade to latest resolvo main #497

Merged
merged 6 commits into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,6 @@ tag-prefix = ""

[profile.bench]
lto = true

[patch.crates-io]
resolvo = { git = "https://github.com/mamba-org/resolvo.git", branch = "main" }
6 changes: 6 additions & 0 deletions crates/rattler_solve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ pub enum SolveError {
/// Error when converting matchspec
#[error(transparent)]
ParseMatchSpecError(#[from] rattler_conda_types::ParseMatchSpecError),

/// To support Resolvo cancellation
Cancelled,
}

impl fmt::Display for SolveError {
Expand All @@ -60,6 +63,9 @@ impl fmt::Display for SolveError {
SolveError::ParseMatchSpecError(e) => {
write!(f, "Error parsing match spec: {e}")
}
SolveError::Cancelled => {
write!(f, "Solve operation has been cancelled")
}
}
}
}
Expand Down
52 changes: 37 additions & 15 deletions crates/rattler_solve/src/resolvo/conda_util.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::resolvo::{CondaDependencyProvider, SolverMatchSpec};
use rattler_conda_types::Version;
use resolvo::{SolvableId, SolverCache, VersionSetId};
use resolvo::{Dependencies, SolvableId, SolverCache, VersionSetId};
use std::cmp::Ordering;
use std::collections::HashMap;

Expand Down Expand Up @@ -49,23 +49,37 @@ pub(super) fn compare_candidates<'a>(

// Otherwise, compare the dependencies of the variants. If there are similar
// dependencies select the variant that selects the highest version of the dependency.
let a_match_specs = solver
let a_dependencies = solver
.get_or_cache_dependencies(a)
.requirements
.iter()
.map(|id| (*id, pool.resolve_version_set(*id)));
let b_match_specs = solver
.expect("should not get here, resolution process aborted");
let b_dependencies = solver
.get_or_cache_dependencies(b)
.requirements
.iter()
.map(|id| (*id, pool.resolve_version_set(*id)));

let b_specs_by_name: HashMap<_, _> = b_match_specs
.map(|(spec_id, _)| (pool.resolve_version_set_package_name(spec_id), spec_id))
.collect();
.expect("should not get here, resolution process aborted");

// If the MatchSpecs are known use these
// map these into a HashMap<PackageName, VersionSetId>
// for comparison later
let (a_specs_by_name, b_specs_by_name) =
if let (Dependencies::Known(a_known), Dependencies::Known(b_known)) =
(a_dependencies, b_dependencies)
{
let a_match_specs = a_known
.requirements
.iter()
.map(|id| (*id, pool.resolve_version_set(*id)))
.map(|(spec_id, _)| (pool.resolve_version_set_package_name(spec_id), spec_id))
.collect::<HashMap<_, _>>();

let a_specs_by_name =
a_match_specs.map(|(spec_id, _)| (pool.resolve_version_set_package_name(spec_id), spec_id));
let b_match_specs = b_known
.requirements
.iter()
.map(|id| (*id, pool.resolve_version_set(*id)))
.map(|(spec_id, _)| (pool.resolve_version_set_package_name(spec_id), spec_id))
.collect::<HashMap<_, _>>();
(a_match_specs, b_match_specs)
} else {
(HashMap::new(), HashMap::new())
};

let mut total_score = 0;
for (a_dep_name, a_spec_id) in a_specs_by_name {
Expand Down Expand Up @@ -132,6 +146,14 @@ pub(super) fn find_highest_version<'a>(
.entry(match_spec_id)
.or_insert_with(|| {
let candidates = solver.get_or_cache_matching_candidates(match_spec_id);

// Err only happens on cancellation, so we will not continue anyways
let candidates = if let Ok(candidates) = candidates {
candidates
} else {
return None;
};

candidates
.iter()
.map(|id| solver.pool().resolve_solvable(*id).inner())
Expand Down
30 changes: 20 additions & 10 deletions crates/rattler_solve/src/resolvo/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ use rattler_conda_types::{
RepoDataRecord,
};
use resolvo::{
Candidates, Dependencies, DependencyProvider, NameId, Pool, SolvableDisplay, SolvableId,
Solver as LibSolvRsSolver, SolverCache, VersionSet, VersionSetId,
Candidates, Dependencies, DependencyProvider, KnownDependencies, NameId, Pool, SolvableDisplay,
SolvableId, Solver as LibSolvRsSolver, SolverCache, UnsolvableOrCancelled, VersionSet,
VersionSetId,
};
use std::{
cell::RefCell,
Expand Down Expand Up @@ -357,12 +358,12 @@ impl<'a> DependencyProvider<SolverMatchSpec<'a>> for CondaDependencyProvider<'a>
}

fn get_dependencies(&self, solvable: SolvableId) -> Dependencies {
let mut dependencies = KnownDependencies::default();
let SolverPackageRecord::Record(rec) = self.pool.resolve_solvable(solvable).inner() else {
return Dependencies::default();
return Dependencies::Known(dependencies);
};

let mut parse_match_spec_cache = self.parse_match_spec_cache.borrow_mut();
let mut dependencies = Dependencies::default();
for depends in rec.package_record.depends.iter() {
let version_set_id =
parse_match_spec(&self.pool, depends, &mut parse_match_spec_cache).unwrap();
Expand All @@ -375,7 +376,7 @@ impl<'a> DependencyProvider<SolverMatchSpec<'a>> for CondaDependencyProvider<'a>
dependencies.constrains.push(version_set_id);
}

dependencies
Dependencies::Known(dependencies)
}
}

Expand Down Expand Up @@ -436,11 +437,20 @@ impl super::SolverImpl for Solver {

// Construct a solver and solve the problems in the queue
let mut solver = LibSolvRsSolver::new(provider);
let solvables = solver.solve(root_requirements).map_err(|problem| {
SolveError::Unsolvable(vec![problem
.display_user_friendly(&solver, &CondaSolvableDisplay)
.to_string()])
})?;
let solvables = solver
.solve(root_requirements)
.map_err(|unsolvable_or_cancelled| {
match unsolvable_or_cancelled {
UnsolvableOrCancelled::Unsolvable(problem) => {
SolveError::Unsolvable(vec![problem
.display_user_friendly(&solver, &CondaSolvableDisplay)
.to_string()])
}
// We are not doing this as of yet
// put a generic message in here for now
UnsolvableOrCancelled::Cancelled(_) => SolveError::Cancelled,
}
})?;

// Get the resulting packages from the solver.
let required_records = solvables
Expand Down
Loading