Skip to content

Commit 3e973d7

Browse files
committed
Use a Vec for incompatibilities and package assignments
1 parent dd3836c commit 3e973d7

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(),
@@ -105,7 +104,8 @@ impl<DP: DependencyProvider> State<DP> {
105104
// to evaluate first the newest incompatibilities.
106105
let mut conflict_id = None;
107106
// We only care about incompatibilities if it contains the current package.
108-
for &incompat_id in self.incompatibilities[&current_package].iter().rev() {
107+
let idx = current_package.0 as usize;
108+
for &incompat_id in self.incompatibilities[idx].iter().rev() {
109109
let current_incompat = &mut self.incompatibility_store[incompat_id];
110110
if self.partial_solution.is_contradicted(current_incompat) {
111111
continue;
@@ -170,7 +170,6 @@ impl<DP: DependencyProvider> State<DP> {
170170

171171
/// Return the root cause or the terminal incompatibility.
172172
/// CF <https://github.com/dart-lang/pub/blob/master/doc/solver.md#unit-propagation>
173-
#[allow(clippy::type_complexity)]
174173
fn conflict_resolution(
175174
&mut self,
176175
incompatibility: IncompDpId<DP>,
@@ -250,6 +249,14 @@ impl<DP: DependencyProvider> State<DP> {
250249
/// We could collapse them into { foo (1.0.0 ∪ 1.1.0), not bar ^1.0.0 }
251250
/// without having to check the existence of other versions though.
252251
fn merge_incompatibility(&mut self, mut id: IncompDpId<DP>) {
252+
fn get_or_default<T>(v: &mut Vec<Vec<Id<T>>>, package_id: PackageId) -> &mut Vec<Id<T>> {
253+
let pkg_idx = package_id.0 as usize;
254+
if pkg_idx + 1 > v.len() {
255+
v.resize(pkg_idx + 1, Vec::new());
256+
}
257+
&mut v[pkg_idx]
258+
}
259+
253260
if let Some((pid1, pid2)) = self.incompatibility_store[id].as_dependency() {
254261
// If we are a dependency, there's a good chance we can be merged with a previous dependency
255262
let deps_lookup = self.merged_dependencies.entry((pid1, pid2)).or_default();
@@ -260,10 +267,7 @@ impl<DP: DependencyProvider> State<DP> {
260267
}) {
261268
let new = self.incompatibility_store.alloc(merged);
262269
for (package_id, _) in self.incompatibility_store[new].iter() {
263-
self.incompatibilities
264-
.entry(package_id)
265-
.or_default()
266-
.retain(|id| id != past);
270+
get_or_default(&mut self.incompatibilities, package_id).retain(|id| id != past);
267271
}
268272
*past = new;
269273
id = new;
@@ -272,13 +276,8 @@ impl<DP: DependencyProvider> State<DP> {
272276
}
273277
}
274278
for (package_id, term) in self.incompatibility_store[id].iter() {
275-
if cfg!(debug_assertions) {
276-
assert_ne!(term, Term::any());
277-
}
278-
self.incompatibilities
279-
.entry(package_id)
280-
.or_default()
281-
.push(id);
279+
debug_assert_ne!(term, Term::any());
280+
get_or_default(&mut self.incompatibilities, package_id).push(id);
282281
}
283282
}
284283

0 commit comments

Comments
 (0)