|
3 | 3 | //! A Memory acts like a structured partial solution |
4 | 4 | //! where terms are regrouped by package in a [Map](crate::type_aliases::Map). |
5 | 5 |
|
| 6 | +use std::cmp::Reverse; |
6 | 7 | use std::fmt::{Debug, Display}; |
7 | 8 | use std::hash::BuildHasherDefault; |
8 | 9 |
|
@@ -66,8 +67,12 @@ pub(crate) struct PartialSolution<DP: DependencyProvider> { |
66 | 67 | /// The undecided packages order by their `Priority`. |
67 | 68 | /// |
68 | 69 | /// The max heap allows quickly `pop`ing the highest priority package. |
| 70 | + /// |
| 71 | + /// The `Reverse<u32>` is the discovery order of packages used as tiebreaker. Its order is that |
| 72 | + /// of a breadth-first search. |
| 73 | + #[allow(clippy::type_complexity)] |
69 | 74 | prioritized_potential_packages: |
70 | | - PriorityQueue<Id<DP::P>, DP::Priority, BuildHasherDefault<FxHasher>>, |
| 75 | + PriorityQueue<Id<DP::P>, (DP::Priority, Reverse<u32>), BuildHasherDefault<FxHasher>>, |
71 | 76 | /// Whether we have never backtracked, to enable fast path optimizations. |
72 | 77 | has_ever_backtracked: bool, |
73 | 78 | } |
@@ -330,7 +335,7 @@ impl<DP: DependencyProvider> PartialSolution<DP> { |
330 | 335 | .filter_map(|(&p, pa)| pa.assignments_intersection.potential_package_filter(p)) |
331 | 336 | .for_each(|(p, r)| { |
332 | 337 | let priority = prioritizer(p, r); |
333 | | - prioritized_potential_packages.push(p, priority); |
| 338 | + prioritized_potential_packages.push(p, (priority, Reverse(p.into_raw() as u32))); |
334 | 339 | }); |
335 | 340 | self.prioritize_decision_level = self.package_assignments.len(); |
336 | 341 | prioritized_potential_packages.pop().map(|(p, _)| p) |
|
0 commit comments