Skip to content

Commit 5cedffb

Browse files
committed
Use a Vec for incompatibilities and package assignments
1 parent 8b353ff commit 5cedffb

File tree

4 files changed

+175
-188
lines changed

4 files changed

+175
-188
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 & 20 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, PackageArena, PackageId, Set, Term, VersionIndex,
@@ -22,12 +22,10 @@ pub(crate) struct State<DP: DependencyProvider> {
2222
root_package_id: PackageId,
2323
root_version_index: VersionIndex,
2424

25-
#[allow(clippy::type_complexity)]
26-
incompatibilities: Map<PackageId, 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<(PackageId, PackageId), SmallVec<[IncompDpId<DP>; 4]>>,
3230

3331
/// Partial solution.
@@ -51,13 +49,14 @@ impl<DP: DependencyProvider> State<DP> {
5149
root_package_id,
5250
root_version_index,
5351
));
54-
let mut incompatibilities = Map::default();
55-
incompatibilities.insert(root_package_id, vec![not_root_id]);
52+
let root_package_idx = root_package_id.0 as usize;
53+
let mut incompatibilities = vec![vec![]; root_package_idx + 1];
54+
incompatibilities[root_package_idx].push(not_root_id);
5655
Self {
5756
root_package_id,
5857
root_version_index,
5958
incompatibilities,
60-
partial_solution: PartialSolution::empty(),
59+
partial_solution: PartialSolution::empty(root_package_id),
6160
incompatibility_store,
6261
unit_propagation_buffer: Vec::new(),
6362
merged_dependencies: Map::default(),
@@ -107,7 +106,8 @@ impl<DP: DependencyProvider> State<DP> {
107106
// to evaluate first the newest incompatibilities.
108107
let mut conflict_id = None;
109108
// We only care about incompatibilities if it contains the current package.
110-
for &incompat_id in self.incompatibilities[&current_package].iter().rev() {
109+
let idx = current_package.0 as usize;
110+
for &incompat_id in self.incompatibilities[idx].iter().rev() {
111111
let current_incompat = &mut self.incompatibility_store[incompat_id];
112112
if self.partial_solution.is_contradicted(current_incompat) {
113113
continue;
@@ -173,7 +173,6 @@ impl<DP: DependencyProvider> State<DP> {
173173
/// Return the root cause or the terminal incompatibility.
174174
/// CF <https://github.com/dart-lang/pub/blob/master/doc/solver.md#unit-propagation>
175175
#[cold]
176-
#[allow(clippy::type_complexity)]
177176
fn conflict_resolution(
178177
&mut self,
179178
incompatibility: IncompDpId<DP>,
@@ -253,6 +252,14 @@ impl<DP: DependencyProvider> State<DP> {
253252
/// We could collapse them into { foo (1.0.0 ∪ 1.1.0), not bar ^1.0.0 }
254253
/// without having to check the existence of other versions though.
255254
fn merge_incompatibility(&mut self, mut id: IncompDpId<DP>) {
255+
fn get_or_default<T>(v: &mut Vec<Vec<Id<T>>>, package_id: PackageId) -> &mut Vec<Id<T>> {
256+
let pkg_idx = package_id.0 as usize;
257+
if pkg_idx + 1 > v.len() {
258+
v.resize(pkg_idx + 1, Vec::new());
259+
}
260+
&mut v[pkg_idx]
261+
}
262+
256263
if let Some((pid1, pid2)) = self.incompatibility_store[id].as_dependency() {
257264
// If we are a dependency, there's a good chance we can be merged with a previous dependency
258265
let deps_lookup = self.merged_dependencies.entry((pid1, pid2)).or_default();
@@ -263,10 +270,7 @@ impl<DP: DependencyProvider> State<DP> {
263270
}) {
264271
let new = self.incompatibility_store.alloc(merged);
265272
for (package_id, _) in self.incompatibility_store[new].iter() {
266-
self.incompatibilities
267-
.entry(package_id)
268-
.or_default()
269-
.retain(|id| id != past);
273+
get_or_default(&mut self.incompatibilities, package_id).retain(|id| id != past);
270274
}
271275
*past = new;
272276
id = new;
@@ -275,13 +279,8 @@ impl<DP: DependencyProvider> State<DP> {
275279
}
276280
}
277281
for (package_id, term) in self.incompatibility_store[id].iter() {
278-
if cfg!(debug_assertions) {
279-
assert_ne!(term, Term::any());
280-
}
281-
self.incompatibilities
282-
.entry(package_id)
283-
.or_default()
284-
.push(id);
282+
debug_assert_ne!(term, Term::any());
283+
get_or_default(&mut self.incompatibilities, package_id).push(id);
285284
}
286285
}
287286

0 commit comments

Comments
 (0)