@@ -97,11 +97,8 @@ pub fn resolve<DP: DependencyProvider>(
97
97
98
98
let Some ( highest_priority_pkg) =
99
99
state. partial_solution . pick_highest_priority_pkg ( |p, r| {
100
- dependency_provider. prioritize (
101
- & state. package_store [ p] ,
102
- r,
103
- state. conflict_count . get ( & p) . cloned ( ) . unwrap_or_default ( ) ,
104
- )
100
+ let statis = PackageResolutionStatistics :: new ( p, & state. conflict_count ) ;
101
+ dependency_provider. prioritize ( & state. package_store [ p] , r, & statis)
105
102
} )
106
103
else {
107
104
return Ok ( state
@@ -203,6 +200,46 @@ pub enum Dependencies<P: Package, VS: VersionSet, M: Eq + Clone + Debug + Displa
203
200
Available ( DependencyConstraints < P , VS > ) ,
204
201
}
205
202
203
+ /// Some statistics about how much trouble the resolver has had with a package.
204
+ pub struct PackageResolutionStatistics {
205
+ discovery_order : u32 ,
206
+ conflict_count : u32 ,
207
+ }
208
+
209
+ impl PackageResolutionStatistics {
210
+ fn new < P : Package > ( pid : Id < P > , conflict_count : & Map < Id < P > , u32 > ) -> Self {
211
+ Self {
212
+ discovery_order : pid. into_raw ( ) as u32 ,
213
+ conflict_count : conflict_count. get ( & pid) . cloned ( ) . unwrap_or_default ( ) ,
214
+ }
215
+ }
216
+
217
+ /// The number of packages resolution new about the first time this package was mentioned.
218
+ ///
219
+ /// The root package will return `0`. It's direct dependencies will start at `1` and go up from there.
220
+ /// Prioritizing based on this value directly will lead to a depth first search of the resolution graph.
221
+ /// Prioritizing based on the reverse of this value will lead to a breadth first search of the resolution graph.
222
+ ///
223
+ /// Note: The exact values depend on implementation details of PubGrub and its dependencies.
224
+ /// So should not be relied on and may change between any lock file update.
225
+ pub fn discovery_order ( & self ) -> u32 {
226
+ self . discovery_order
227
+ }
228
+
229
+ /// The number of times this package was involved in a conflict that caused a back jump.
230
+ ///
231
+ /// When resolution is proceeding normally, this value will stay at `0` for all packages.
232
+ /// Therefore, using this for prioritization will not affect the properties of simple cases
233
+ /// like checking a lock file.
234
+ /// Prioritizing based on this value directly allows the resolver to focus on the packages
235
+ /// it is having the most problems with.
236
+ ///
237
+ /// Note: The exact values depend on implementation details of PubGrub. So should not be relied on and may change.
238
+ pub fn conflict_count ( & self ) -> u32 {
239
+ self . conflict_count
240
+ }
241
+ }
242
+
206
243
/// Trait that allows the algorithm to retrieve available packages and their dependencies.
207
244
/// An implementor needs to be supplied to the [resolve] function.
208
245
pub trait DependencyProvider {
@@ -238,8 +275,8 @@ pub trait DependencyProvider {
238
275
///
239
276
/// Every time such a decision must be made, the resolver looks at all the potential valid
240
277
/// packages that have changed, and a asks the dependency provider how important each one is.
241
- /// For each one it calls `prioritize` with the name of the package and the current set of
242
- /// acceptable versions.
278
+ /// For each one it calls `prioritize` with the name of the package, the current set of
279
+ /// acceptable versions, and some statistics about how much trouble the resolver has had with that package .
243
280
/// The resolver will then pick the package with the highes priority from all the potential valid
244
281
/// packages.
245
282
///
@@ -262,7 +299,7 @@ pub trait DependencyProvider {
262
299
& self ,
263
300
package : & Self :: P ,
264
301
range : & Self :: VS ,
265
- conflict_count : u32 ,
302
+ statis : & PackageResolutionStatistics ,
266
303
) -> Self :: Priority ;
267
304
/// The type returned from `prioritize`. The resolver does not care what type this is
268
305
/// as long as it can pick a largest one and clone it.
0 commit comments