Skip to content

Commit 1611705

Browse files
committed
Use a Vec for incompatibilities and package assignments
1 parent 1722264 commit 1611705

File tree

4 files changed

+163
-180
lines changed

4 files changed

+163
-180
lines changed

src/internal/arena.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use std::ops::{Index, IndexMut, Range};
1010
/// that we actually don't need since it is phantom.
1111
///
1212
/// <https://github.com/rust-lang/rust/issues/26925>
13+
#[repr(transparent)]
1314
pub(crate) struct Id<T> {
1415
raw: u32,
1516
_ty: PhantomData<fn() -> T>,

src/internal/core.rs

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use smallvec::SmallVec;
99

1010
use crate::{
1111
internal::{
12-
Arena, DecisionLevel, IncompDpId, Incompatibility, PartialSolution, Relation,
12+
Arena, DecisionLevel, Id, IncompDpId, Incompatibility, PartialSolution, Relation,
1313
SatisfierSearch,
1414
},
1515
DependencyProvider, DerivationTree, Map, Package, PackageArena, Set, Term, Version, VersionSet,
@@ -21,12 +21,10 @@ pub(crate) struct State<DP: DependencyProvider> {
2121
root_package: Package,
2222
root_version: Version,
2323

24-
#[allow(clippy::type_complexity)]
25-
incompatibilities: Map<Package, Vec<IncompDpId<DP>>>,
24+
incompatibilities: Vec<Vec<IncompDpId<DP>>>,
2625

2726
/// All incompatibilities expressing dependencies,
2827
/// with common dependents merged.
29-
#[allow(clippy::type_complexity)]
3028
merged_dependencies: Map<(Package, Package), SmallVec<[IncompDpId<DP>; 4]>>,
3129

3230
/// Partial solution.
@@ -48,13 +46,14 @@ impl<DP: DependencyProvider> State<DP> {
4846
let mut incompatibility_store = Arena::new();
4947
let not_root_id =
5048
incompatibility_store.alloc(Incompatibility::not_root(root_package, root_version));
51-
let mut incompatibilities = Map::default();
52-
incompatibilities.insert(root_package, vec![not_root_id]);
49+
let root_package_idx = root_package.0 as usize;
50+
let mut incompatibilities = vec![vec![]; root_package_idx + 1];
51+
incompatibilities[root_package_idx].push(not_root_id);
5352
Self {
5453
root_package,
5554
root_version,
5655
incompatibilities,
57-
partial_solution: PartialSolution::empty(),
56+
partial_solution: PartialSolution::empty(root_package),
5857
incompatibility_store,
5958
unit_propagation_buffer: Vec::new(),
6059
merged_dependencies: Map::default(),
@@ -102,7 +101,8 @@ impl<DP: DependencyProvider> State<DP> {
102101
// to evaluate first the newest incompatibilities.
103102
let mut conflict_id = None;
104103
// We only care about incompatibilities if it contains the current package.
105-
for &incompat_id in self.incompatibilities[&current_package].iter().rev() {
104+
let idx = current_package.0 as usize;
105+
for &incompat_id in self.incompatibilities[idx].iter().rev() {
106106
let current_incompat = &mut self.incompatibility_store[incompat_id];
107107
if self.partial_solution.is_contradicted(current_incompat) {
108108
continue;
@@ -167,7 +167,6 @@ impl<DP: DependencyProvider> State<DP> {
167167

168168
/// Return the root cause or the terminal incompatibility.
169169
/// CF <https://github.com/dart-lang/pub/blob/master/doc/solver.md#unit-propagation>
170-
#[allow(clippy::type_complexity)]
171170
fn conflict_resolution(
172171
&mut self,
173172
incompatibility: IncompDpId<DP>,
@@ -247,6 +246,14 @@ impl<DP: DependencyProvider> State<DP> {
247246
/// We could collapse them into { foo (1.0.0 ∪ 1.1.0), not bar ^1.0.0 }
248247
/// without having to check the existence of other versions though.
249248
fn merge_incompatibility(&mut self, mut id: IncompDpId<DP>) {
249+
fn get_or_default<T>(v: &mut Vec<Vec<Id<T>>>, pkg: Package) -> &mut Vec<Id<T>> {
250+
let pkg_idx = pkg.0 as usize;
251+
if pkg_idx + 1 > v.len() {
252+
v.resize(pkg_idx + 1, Vec::new());
253+
}
254+
&mut v[pkg_idx]
255+
}
256+
250257
if let Some((p1, p2)) = self.incompatibility_store[id].as_dependency() {
251258
// If we are a dependency, there's a good chance we can be merged with a previous dependency
252259
let deps_lookup = self.merged_dependencies.entry((p1, p2)).or_default();
@@ -257,10 +264,7 @@ impl<DP: DependencyProvider> State<DP> {
257264
}) {
258265
let new = self.incompatibility_store.alloc(merged);
259266
for (pkg, _) in self.incompatibility_store[new].iter() {
260-
self.incompatibilities
261-
.entry(pkg)
262-
.or_default()
263-
.retain(|id| id != past);
267+
get_or_default(&mut self.incompatibilities, pkg).retain(|id| id != past);
264268
}
265269
*past = new;
266270
id = new;
@@ -269,10 +273,8 @@ impl<DP: DependencyProvider> State<DP> {
269273
}
270274
}
271275
for (pkg, term) in self.incompatibility_store[id].iter() {
272-
if cfg!(debug_assertions) {
273-
assert_ne!(term, Term::any());
274-
}
275-
self.incompatibilities.entry(pkg).or_default().push(id);
276+
debug_assert_ne!(term, Term::any());
277+
get_or_default(&mut self.incompatibilities, pkg).push(id);
276278
}
277279
}
278280

0 commit comments

Comments
 (0)