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

Update the docs for prioritize #312

Merged
merged 3 commits into from
Jan 29, 2025
Merged
Changes from 1 commit
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
60 changes: 25 additions & 35 deletions src/solver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,54 +293,44 @@ pub trait DependencyProvider {
/// assign [`String`] as placeholder.
type M: Eq + Clone + Debug + Display;

/// [Decision making](https://github.com/dart-lang/pub/blob/master/doc/solver.md#decision-making)
/// is the process of choosing the next package
/// and version that will be appended to the partial solution.
/// The type returned from `prioritize`. The resolver does not care what type this is
/// as long as it can pick a largest one and clone it.
///
/// Every time such a decision must be made, the resolver looks at all the potential valid
/// packages that have changed, and a asks the dependency provider how important each one is.
/// For each one it calls `prioritize` with the name of the package and the current set of
/// acceptable versions.
/// The resolver will then pick the package with the highes priority from all the potential valid
/// packages.
/// [`Reverse`](std::cmp::Reverse) can be useful if you want to pick the package with
/// the fewest versions that match the outstanding constraint.
type Priority: Ord + Clone;

/// The kind of error returned from these methods.
///
/// The strategy employed to prioritize packages
/// cannot change the existence of a solution or not,
/// but can drastically change the performances of the solver,
/// or the properties of the solution.
/// The documentation of Pub (PubGrub implementation for the dart programming language)
/// states the following:
/// Returning this signals that resolution should fail with this error.
type Err: Error + 'static;

/// Determine the order in which versions are chosen for packages.
///
/// > Pub chooses the latest matching version of the package
/// > with the fewest versions that match the outstanding constraint.
/// > This tends to find conflicts earlier if any exist,
/// > since these packages will run out of versions to try more quickly.
/// > But there's likely room for improvement in these heuristics.
/// Decisions are always made for the highest priority package first. The order of decisions
/// determines which solution is chosen and can drastically change the performances of the
/// solver. If there is a conflict between two package versions, the package with the higher
/// priority is preserved and the lower priority gets discarded. Usually, you want to decide
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is a conflict between two package versions, the priority is preserved and the lower priority gets discarded.

I'm not following. What scenario are you trying to describe?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the word "decision".

Say:
choose A
decide A 2
choose B
decide B 2

and then we discover A 2 -> C 1, B 2 -> C 2.

In this case, we will next try B 1, not A 1: The version of A 2 gets preserved, while B 2 gets discarded.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps: "If there is a conflict between two package versions, decisions will be backtracked until the lower priority package version is discarded preserving the higher priority package." or something.

/// more certain packages (e.g. those with a single version constraint) and packages with more
/// conflicts first.
///
/// The `package_conflicts_counts` argument provides access to some other heuristics that
/// are production users have found useful. Although the exact meaning/efficacy of those arguments may change.
/// are production users have found useful. Although the exact meaning/efficacy of those
/// arguments may change.
///
/// If two packages have the same priority, PubGrub will biased toward a breadth first search.
/// The function is called once for each new package and then cached until we detect a
/// (potential) change to `range`, otherwise it is cached, assuming that the priority only
/// depends on the arguments to this function.
///
/// Note: the resolver may call this even when the range has not changed,
/// if it is more efficient for the resolvers internal data structures.
/// If two packages have the same priority, PubGrub will bias toward a breadth first search.
fn prioritize(
&self,
package: &Self::P,
range: &Self::VS,
// TODO(konsti): Are we always refreshing the priorities when `PackageResolutionStatistics`
// changed for a package?
package_conflicts_counts: &PackageResolutionStatistics,
) -> Self::Priority;
/// The type returned from `prioritize`. The resolver does not care what type this is
/// as long as it can pick a largest one and clone it.
///
/// [`Reverse`](std::cmp::Reverse) can be useful if you want to pick the package with
/// the fewest versions that match the outstanding constraint.
type Priority: Ord + Clone;

/// The kind of error returned from these methods.
///
/// Returning this signals that resolution should fail with this error.
type Err: Error + 'static;

/// Once the resolver has found the highest `Priority` package from all potential valid
/// packages, it needs to know what version of that package to use. The most common pattern
Expand Down
Loading