Skip to content

Commit

Permalink
less O(n^2)
Browse files Browse the repository at this point in the history
  • Loading branch information
Eh2406 committed May 28, 2022
1 parent c15fb4c commit 6863f93
Showing 1 changed file with 23 additions and 6 deletions.
29 changes: 23 additions & 6 deletions src/internal/partial_solution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub struct PartialSolution<P: Package, VS: VersionSet, Priority: Ord + Clone> {
current_decision_level: DecisionLevel,
package_assignments: FnvIndexMap<P, PackageAssignments<P, VS>>,
prioritized_potential_packages: PriorityQueue<P, Priority, BuildHasherDefault<FxHasher>>,
just_backtracked: bool,
changed_this_decision_level: usize,
}

impl<P: Package, VS: VersionSet, Priority: Ord + Clone> Display
Expand Down Expand Up @@ -138,7 +138,7 @@ impl<P: Package, VS: VersionSet, Priority: Ord + Clone> PartialSolution<P, VS, P
current_decision_level: DecisionLevel(0),
package_assignments: FnvIndexMap::default(),
prioritized_potential_packages: PriorityQueue::default(),
just_backtracked: false,
changed_this_decision_level: 0,
}
}

Expand All @@ -157,6 +157,10 @@ impl<P: Package, VS: VersionSet, Priority: Ord + Clone> PartialSolution<P, VS, P
}
},
}
assert_eq!(
self.changed_this_decision_level,
self.package_assignments.len()
);
}
let new_idx = self.current_decision_level.0 as usize;
self.current_decision_level = self.current_decision_level.increment();
Expand Down Expand Up @@ -191,8 +195,10 @@ impl<P: Package, VS: VersionSet, Priority: Ord + Clone> PartialSolution<P, VS, P
cause,
};
self.next_global_index += 1;
let pa_last_index = self.package_assignments.len().saturating_sub(1);
match self.package_assignments.entry(package) {
Entry::Occupied(mut occupied) => {
let idx = occupied.index();
let mut pa = occupied.get_mut();
pa.highest_decision_level = self.current_decision_level;
match &mut pa.assignments_intersection {
Expand All @@ -202,11 +208,21 @@ impl<P: Package, VS: VersionSet, Priority: Ord + Clone> PartialSolution<P, VS, P
}
AssignmentsIntersection::Derivations(t) => {
*t = t.intersection(&term);
if t.is_positive() {
// we can use `swap_indices` to make `changed_this_decision_level` only go down by 1
// but the copying is slower then the larger search
self.changed_this_decision_level =
std::cmp::min(self.changed_this_decision_level, idx);
}
}
}
pa.dated_derivations.push(dated_derivation);
}
Entry::Vacant(v) => {
if term.is_positive() {
self.changed_this_decision_level =
std::cmp::min(self.changed_this_decision_level, pa_last_index);
}
v.insert(PackageAssignments {
smallest_decision_level: self.current_decision_level,
highest_decision_level: self.current_decision_level,
Expand All @@ -218,19 +234,20 @@ impl<P: Package, VS: VersionSet, Priority: Ord + Clone> PartialSolution<P, VS, P
}

pub fn prioritize(&mut self, prioritizer: impl Fn(&P, &VS) -> Priority) -> Option<P> {
let check_all = self.just_backtracked;
self.just_backtracked = false;
let check_all = self.changed_this_decision_level
== self.current_decision_level.0.saturating_sub(1) as usize;
let current_decision_level = self.current_decision_level;
let package_assignments = &self.package_assignments;
let prioritized_potential_packages = &mut self.prioritized_potential_packages;
(self.current_decision_level.0 as usize..package_assignments.len())
(self.changed_this_decision_level..package_assignments.len())
.map(|i| package_assignments.get_index(i).unwrap())
.filter(|(_, pa)| check_all || pa.highest_decision_level == current_decision_level)
.filter_map(|(p, pa)| pa.assignments_intersection.potential_package_filter(p))
.for_each(|(p, r)| {
let priority = prioritizer(&p, r);
prioritized_potential_packages.push(p.clone(), priority);
});
self.changed_this_decision_level = package_assignments.len();
prioritized_potential_packages.pop().map(|(p, _)| p)
}

Expand Down Expand Up @@ -295,7 +312,7 @@ impl<P: Package, VS: VersionSet, Priority: Ord + Clone> PartialSolution<P, VS, P
}
});
self.prioritized_potential_packages.clear();
self.just_backtracked = true;
self.changed_this_decision_level = self.current_decision_level.0.saturating_sub(1) as usize;
}

/// We can add the version to the partial solution as a decision
Expand Down

0 comments on commit 6863f93

Please sign in to comment.