Skip to content

Commit e08d032

Browse files
committed
add a helper function
1 parent 8458661 commit e08d032

File tree

1 file changed

+29
-29
lines changed

1 file changed

+29
-29
lines changed

tests/testsuite/support/resolver.rs

+29-29
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,21 @@ fn sat_at_most_one(solver: &mut impl varisat::ExtendFormula, vars: &[varisat::Va
218218
}
219219
}
220220

221+
fn sat_at_most_one_by_key<K: std::hash::Hash + Eq>(
222+
cnf: &mut impl varisat::ExtendFormula,
223+
data: impl Iterator<Item = (K, varisat::Var)>,
224+
) -> HashMap<K, Vec<varisat::Var>> {
225+
// no two packages with the same links set
226+
let mut by_keys: HashMap<K, Vec<varisat::Var>> = HashMap::new();
227+
for (p, v) in data {
228+
by_keys.entry(p).or_default().push(v)
229+
}
230+
for key in by_keys.values() {
231+
sat_at_most_one(cnf, key);
232+
}
233+
by_keys
234+
}
235+
221236
/// Resolution can be reduced to the SAT problem. So this is an alternative implementation
222237
/// of the resolver that uses a SAT library for the hard work. This is intended to be easy to read,
223238
/// as compared to the real resolver.
@@ -243,30 +258,21 @@ impl SatResolve {
243258
.collect();
244259

245260
// no two packages with the same links set
246-
let mut by_links: HashMap<_, Vec<varisat::Var>> = HashMap::new();
247-
for p in registry.iter() {
248-
if let Some(l) = p.links() {
249-
by_links
250-
.entry(l)
251-
.or_default()
252-
.push(var_for_is_packages_used[&p.package_id()])
253-
}
254-
}
255-
for link in by_links.values() {
256-
sat_at_most_one(&mut cnf, link);
257-
}
261+
sat_at_most_one_by_key(
262+
&mut cnf,
263+
registry
264+
.iter()
265+
.map(|s| (s.links(), var_for_is_packages_used[&s.package_id()]))
266+
.filter(|(l, _)| l.is_some()),
267+
);
258268

259269
// no two semver compatible versions of the same package
260-
let mut by_activations_keys: HashMap<_, Vec<varisat::Var>> = HashMap::new();
261-
for p in registry.iter() {
262-
by_activations_keys
263-
.entry(p.package_id().as_activations_key())
264-
.or_default()
265-
.push(var_for_is_packages_used[&p.package_id()])
266-
}
267-
for key in by_activations_keys.values() {
268-
sat_at_most_one(&mut cnf, key);
269-
}
270+
let by_activations_keys = sat_at_most_one_by_key(
271+
&mut cnf,
272+
var_for_is_packages_used
273+
.iter()
274+
.map(|(p, &v)| (p.as_activations_key(), v)),
275+
);
270276

271277
let mut by_name: HashMap<&'static str, Vec<PackageId>> = HashMap::new();
272278

@@ -389,13 +395,7 @@ impl SatResolve {
389395

390396
// a package `can_see` only one version by each name
391397
for (_, see) in can_see.iter() {
392-
let mut by_name: HashMap<&'static str, Vec<varisat::Var>> = HashMap::new();
393-
for ((name, _, _), &var) in see {
394-
by_name.entry(name.as_str()).or_default().push(var);
395-
}
396-
for same_name in by_name.values() {
397-
sat_at_most_one(&mut cnf, same_name);
398-
}
398+
sat_at_most_one_by_key(&mut cnf, see.iter().map(|((name, _, _), &v)| (name, v)));
399399
}
400400
let mut solver = varisat::Solver::new();
401401
solver.add_formula(&cnf);

0 commit comments

Comments
 (0)