Skip to content

Commit c68334f

Browse files
committed
Think of publicly_exports as being in terms of a set of activations_keys
1 parent a25d8e9 commit c68334f

File tree

1 file changed

+40
-24
lines changed

1 file changed

+40
-24
lines changed

tests/testsuite/support/resolver.rs

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -282,49 +282,60 @@ impl SatResolve {
282282

283283
let mut version_selected_for: HashMap<
284284
PackageId,
285-
HashMap<Dependency, HashMap<PackageId, varisat::Var>>,
285+
HashMap<Dependency, HashMap<_, varisat::Var>>,
286286
> = HashMap::new();
287287
// active packages need each of there `deps` to be satisfied
288288
for p in registry.iter() {
289289
graph.add(p.package_id());
290290
for dep in p.dependencies() {
291-
let version: HashMap<PackageId, varisat::Var> = by_name
291+
let mut by_key: HashMap<_, Vec<varisat::Lit>> = HashMap::new();
292+
for &m in by_name
292293
.get(dep.package_name().as_str())
293294
.unwrap_or(&empty_vec)
294295
.iter()
295296
.filter(|&p| dep.matches_id(*p))
296-
.map(|&p| (p, solver.new_var()))
297-
.collect();
298-
// if `p` is active then we need to select one of the versions
299-
let matches: Vec<_> = version
297+
{
298+
by_key
299+
.entry(m.as_activations_key())
300+
.or_default()
301+
.push(var_for_is_packages_used[&m].positive());
302+
}
303+
let keys: HashMap<_, _> = by_key.keys().map(|&k| (k, solver.new_var())).collect();
304+
305+
// if `p` is active then we need to select one of the keys
306+
let matches: Vec<_> = keys
300307
.values()
301308
.map(|v| v.positive())
302309
.chain(Some(var_for_is_packages_used[&p.package_id()].negative()))
303310
.collect();
304311
solver.add_clause(&matches);
305-
for (pid, var) in version.iter() {
306-
// if a version is selected then it needs to be activated
307-
solver.add_clause(&[var.negative(), var_for_is_packages_used[pid].positive()]);
308-
graph.link(p.package_id(), *pid);
312+
313+
// if a key is active then we need to select one of the versions
314+
for (key, vars) in by_key.iter() {
315+
let mut matches = vars.clone();
316+
matches.push(keys[key].negative());
317+
solver.add_clause(&matches);
309318
}
319+
310320
version_selected_for
311321
.entry(p.package_id())
312322
.or_default()
313-
.insert(dep.clone(), version);
323+
.insert(dep.clone(), keys);
314324
}
315325
}
316326

317327
let topological_order = graph.sort();
318328

319-
let mut publicly_exports: HashMap<PackageId, HashMap<PackageId, varisat::Var>> =
320-
HashMap::new();
329+
// we already ensure there is only one version for each `activations_key` so we can think of
330+
// `publicly_exports` as being in terms of a set of `activations_key`s
331+
let mut publicly_exports: HashMap<_, HashMap<_, varisat::Var>> = HashMap::new();
321332

322-
for s in registry.iter() {
333+
for &key in by_activations_keys.keys() {
323334
// everything publicly depends on itself
324335
let var = publicly_exports
325-
.entry(s.package_id())
336+
.entry(key)
326337
.or_default()
327-
.entry(s.package_id())
338+
.entry(key)
328339
.or_insert_with(|| solver.new_var());
329340
solver.add_clause(&[var.positive()]);
330341
}
@@ -336,7 +347,7 @@ impl SatResolve {
336347
for (ver, sel) in versions {
337348
for (&export_pid, &export_var) in publicly_exports[ver].clone().iter() {
338349
let our_var = publicly_exports
339-
.entry(p)
350+
.entry(p.as_activations_key())
340351
.or_default()
341352
.entry(export_pid)
342353
.or_insert_with(|| solver.new_var());
@@ -351,7 +362,9 @@ impl SatResolve {
351362
}
352363
}
353364

354-
let mut can_see: HashMap<PackageId, HashMap<PackageId, varisat::Var>> = HashMap::new();
365+
// we already ensure there is only one version for each `activations_key` so we can think of
366+
// `can_see` as being in terms of a set of `activations_key`s
367+
let mut can_see: HashMap<_, HashMap<_, varisat::Var>> = HashMap::new();
355368

356369
// if `p` `publicly_exports` `export` then it `can_see` `export`
357370
for (&p, exports) in &publicly_exports {
@@ -368,10 +381,10 @@ impl SatResolve {
368381
// if `p` has a `dep` that selected `ver` then it `can_see` all the things that the selected version `publicly_exports`
369382
for (&p, deps) in version_selected_for.iter() {
370383
for (_, versions) in deps {
371-
for (ver, sel) in versions {
372-
for (&export_pid, &export_var) in publicly_exports[ver].iter() {
384+
for (&ver, sel) in versions {
385+
for (&export_pid, &export_var) in publicly_exports[&ver].iter() {
373386
let our_var = can_see
374-
.entry(p)
387+
.entry(p.as_activations_key())
375388
.or_default()
376389
.entry(export_pid)
377390
.or_insert_with(|| solver.new_var());
@@ -387,9 +400,12 @@ impl SatResolve {
387400

388401
// a package `can_see` only one version by each name
389402
for (_, see) in can_see.iter() {
390-
for (_, vers) in by_name.iter() {
391-
let same_name: Vec<_> = vers.iter().filter_map(|p| see.get(p).cloned()).collect();
392-
sat_at_most_one(&mut solver, &same_name);
403+
let mut by_name: HashMap<&'static str, Vec<varisat::Var>> = HashMap::new();
404+
for ((name, _, _), &var) in see {
405+
by_name.entry(name.as_str()).or_default().push(var);
406+
}
407+
for same_name in by_name.values() {
408+
sat_at_most_one(&mut solver, same_name);
393409
}
394410
}
395411

0 commit comments

Comments
 (0)