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
@@ -451,6 +452,28 @@ impl<DP: DependencyProvider> PartialSolution<DP> {
451452 self . has_ever_backtracked = true ;
452453 }
453454
455+ /// Backtrack the partial solution before a particular package was selected.
456+ ///
457+ /// This can be used to switch the order of packages if the previous prioritization was bad.
458+ ///
459+ /// Returns the new decision level on success and an error if the package was not decided on
460+ /// yet.
461+ pub ( crate ) fn backtrack_package ( & mut self , package : Id < DP :: P > ) -> Result < DecisionLevel , ( ) > {
462+ let Some ( decision_level) = self . package_assignments . get_index_of ( & package) else {
463+ return Err ( ( ) ) ;
464+ } ;
465+ let decision_level = DecisionLevel ( decision_level as u32 ) ;
466+ if decision_level > self . current_decision_level {
467+ return Err ( ( ) ) ;
468+ }
469+ debug ! (
470+ "Package backtracking ot decision level {}" ,
471+ decision_level. 0
472+ ) ;
473+ self . backtrack ( decision_level) ;
474+ Ok ( decision_level)
475+ }
476+
454477 /// Add a package version as decision if none of its dependencies conflicts with the partial
455478 /// solution.
456479 ///
You can’t perform that action at this time.
0 commit comments