Skip to content

Commit 8ff1870

Browse files
committed
Use a Vec for incompatibilities and package assignments
1 parent 97cf7aa commit 8ff1870

File tree

4 files changed

+173
-185
lines changed

4 files changed

+173
-185
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, VersionIndex,
@@ -22,12 +22,10 @@ pub(crate) struct State<DP: DependencyProvider> {
2222
root_package: Package,
2323
root_version_index: VersionIndex,
2424

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

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

3331
/// Partial solution.
@@ -49,13 +47,14 @@ impl<DP: DependencyProvider> State<DP> {
4947
let mut incompatibility_store = Arena::new();
5048
let not_root_id = incompatibility_store
5149
.alloc(Incompatibility::not_root(root_package, root_version_index));
52-
let mut incompatibilities = Map::default();
53-
incompatibilities.insert(root_package, vec![not_root_id]);
50+
let root_package_idx = root_package.0 as usize;
51+
let mut incompatibilities = vec![vec![]; root_package_idx + 1];
52+
incompatibilities[root_package_idx].push(not_root_id);
5453
Self {
5554
root_package,
5655
root_version_index,
5756
incompatibilities,
58-
partial_solution: PartialSolution::empty(),
57+
partial_solution: PartialSolution::empty(root_package),
5958
incompatibility_store,
6059
unit_propagation_buffer: Vec::new(),
6160
merged_dependencies: Map::default(),
@@ -103,7 +102,8 @@ impl<DP: DependencyProvider> State<DP> {
103102
// to evaluate first the newest incompatibilities.
104103
let mut conflict_id = None;
105104
// We only care about incompatibilities if it contains the current package.
106-
for &incompat_id in self.incompatibilities[&current_package].iter().rev() {
105+
let idx = current_package.0 as usize;
106+
for &incompat_id in self.incompatibilities[idx].iter().rev() {
107107
let current_incompat = &mut self.incompatibility_store[incompat_id];
108108
if self.partial_solution.is_contradicted(current_incompat) {
109109
continue;
@@ -168,7 +168,6 @@ impl<DP: DependencyProvider> State<DP> {
168168

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

0 commit comments

Comments
 (0)