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
@@ -432,6 +433,28 @@ impl<DP: DependencyProvider> PartialSolution<DP> {
432433 self . has_ever_backtracked = true ;
433434 }
434435
436+ /// Backtrack the partial solution before a particular package was selected.
437+ ///
438+ /// This can be used to switch the order of packages if the previous prioritization was bad.
439+ ///
440+ /// Returns the new decision level on success and an error if the package was not decided on
441+ /// yet.
442+ pub ( crate ) fn backtrack_package ( & mut self , package : Id < DP :: P > ) -> Result < DecisionLevel , ( ) > {
443+ let Some ( decision_level) = self . package_assignments . get_index_of ( & package) else {
444+ return Err ( ( ) ) ;
445+ } ;
446+ let decision_level = DecisionLevel ( decision_level as u32 ) ;
447+ if decision_level > self . current_decision_level {
448+ return Err ( ( ) ) ;
449+ }
450+ debug ! (
451+ "Package backtracking ot decision level {}" ,
452+ decision_level. 0
453+ ) ;
454+ self . backtrack ( decision_level) ;
455+ Ok ( decision_level)
456+ }
457+
435458 /// Add a package version as decision if none of its dependencies conflicts with the partial
436459 /// solution.
437460 ///
You can’t perform that action at this time.
0 commit comments