File tree Expand file tree Collapse file tree 2 files changed +40
-1
lines changed Expand file tree Collapse file tree 2 files changed +40
-1
lines changed Original file line number Diff line number Diff line change @@ -289,7 +289,8 @@ impl<DP: DependencyProvider> State<DP> {
289289 }
290290 }
291291
292- /// Backtracking.
292+ /// After a conflict occurred, backtrack the partial solution to a given decision level, and add
293+ /// the incompatibility if it was new.
293294 fn backtrack (
294295 & mut self ,
295296 incompat : IncompDpId < DP > ,
@@ -305,6 +306,21 @@ impl<DP: DependencyProvider> State<DP> {
305306 }
306307 }
307308
309+ /// Manually backtrack before the given package was selected.
310+ ///
311+ /// This can be used to switch the order of packages if the previous prioritization was bad.
312+ ///
313+ /// Returns the number of the decisions that were backtracked, or `None` if the package was not
314+ /// decided on yet.
315+ pub fn backtrack_package ( & mut self , package : Id < DP :: P > ) -> Option < u32 > {
316+ let base_decision_level = self . partial_solution . current_decision_level ( ) ;
317+ let new_decision_level = self . partial_solution . backtrack_package ( package) . ok ( ) ?;
318+ // Remove contradicted incompatibilities that depend on decisions we just backtracked away.
319+ self . contradicted_incompatibilities
320+ . retain ( |_, dl| * dl <= new_decision_level) ;
321+ Some ( base_decision_level. 0 - new_decision_level. 0 )
322+ }
323+
308324 /// Add this incompatibility into the set of all incompatibilities.
309325 ///
310326 /// PubGrub collapses identical dependencies from adjacent package versions
Original file line number Diff line number Diff line change @@ -7,6 +7,7 @@ use std::cmp::Reverse;
77use std:: fmt:: { Debug , Display } ;
88use std:: hash:: BuildHasherDefault ;
99
10+ use log:: debug;
1011use priority_queue:: PriorityQueue ;
1112use rustc_hash:: FxHasher ;
1213
@@ -435,6 +436,28 @@ impl<DP: DependencyProvider> PartialSolution<DP> {
435436 self . has_ever_backtracked = true ;
436437 }
437438
439+ /// Backtrack the partial solution before a particular package was selected.
440+ ///
441+ /// This can be used to switch the order of packages if the previous prioritization was bad.
442+ ///
443+ /// Returns the new decision level on success and an error if the package was not decided on
444+ /// yet.
445+ pub ( crate ) fn backtrack_package ( & mut self , package : Id < DP :: P > ) -> Result < DecisionLevel , ( ) > {
446+ let Some ( decision_level) = self . package_assignments . get_index_of ( & package) else {
447+ return Err ( ( ) ) ;
448+ } ;
449+ let decision_level = DecisionLevel ( decision_level as u32 ) ;
450+ if decision_level > self . current_decision_level {
451+ return Err ( ( ) ) ;
452+ }
453+ debug ! (
454+ "Package backtracking ot decision level {}" ,
455+ decision_level. 0
456+ ) ;
457+ self . backtrack ( decision_level) ;
458+ Ok ( decision_level)
459+ }
460+
438461 /// Add a package version as decision if none of its dependencies conflicts with the partial
439462 /// solution.
440463 ///
You can’t perform that action at this time.
0 commit comments