1 |
When a slot conflict occurs due to a missed update, and some other |
2 |
similar update(s) are available, add the similar update(s) to the |
3 |
runtime package mask for the same backtracking choice. This reduces |
4 |
minimum number of backtrack tries required to solve the test case |
5 |
for bug 743115 from 7 to 4, where the difference of 3 corresponds |
6 |
to the number of other similar setuptools updates available. |
7 |
|
8 |
Bug: https://bugs.gentoo.org/743115 |
9 |
Signed-off-by: Zac Medico <zmedico@g.o> |
10 |
--- |
11 |
lib/_emerge/depgraph.py | 25 ++++++++++++++++--- |
12 |
lib/_emerge/resolver/backtracking.py | 7 +++--- |
13 |
.../test_slot_operator_missed_update.py | 2 +- |
14 |
3 files changed, 26 insertions(+), 8 deletions(-) |
15 |
|
16 |
diff --git a/lib/_emerge/depgraph.py b/lib/_emerge/depgraph.py |
17 |
index 7281d8692..2a840b2ca 100644 |
18 |
--- a/lib/_emerge/depgraph.py |
19 |
+++ b/lib/_emerge/depgraph.py |
20 |
@@ -1795,15 +1795,32 @@ class depgraph: |
21 |
self._dynamic_config._parent_atoms.get(to_be_masked, set()) |
22 |
conflict_atoms = set(parent_atom for parent_atom in all_parents \ |
23 |
if parent_atom not in parent_atoms) |
24 |
- backtrack_data.append((to_be_masked, conflict_atoms)) |
25 |
+ |
26 |
+ similar_pkgs = [] |
27 |
+ if conflict_atoms: |
28 |
+ # If the conflict has been triggered by a missed update, then |
29 |
+ # we can avoid excessive backtracking if we detect similar missed |
30 |
+ # updates and mask them as part of the same backtracking choice. |
31 |
+ for similar_pkg in self._iter_similar_available(to_be_masked, slot_atom): |
32 |
+ if similar_pkg in conflict_pkgs: |
33 |
+ continue |
34 |
+ similar_conflict_atoms = [] |
35 |
+ for parent_atom in conflict_atoms: |
36 |
+ parent, atom = parent_atom |
37 |
+ if not atom.match(similar_pkg): |
38 |
+ similar_conflict_atoms.append(parent_atom) |
39 |
+ if similar_conflict_atoms: |
40 |
+ similar_pkgs.append((similar_pkg, set(similar_conflict_atoms))) |
41 |
+ similar_pkgs.append((to_be_masked, conflict_atoms)) |
42 |
+ backtrack_data.append(tuple(similar_pkgs)) |
43 |
|
44 |
# Prefer choices that minimize conflict atoms. This is intended |
45 |
# to take precedence over the earlier package version sort. The |
46 |
# package version sort is still needed or else choices for the |
47 |
# testOverlapSlotConflict method of VirtualMinimizeChildrenTestCase |
48 |
# become non-deterministic. |
49 |
- backtrack_data.sort(key=lambda item: len(item[1])) |
50 |
- to_be_masked = backtrack_data[-1][0] |
51 |
+ backtrack_data.sort(key=lambda similar_pkgs: max(len(item[1]) for item in similar_pkgs)) |
52 |
+ to_be_masked = [item[0] for item in backtrack_data[-1]] |
53 |
|
54 |
self._dynamic_config._backtrack_infos.setdefault( |
55 |
"slot conflict", []).append(backtrack_data) |
56 |
@@ -1814,7 +1831,7 @@ class depgraph: |
57 |
"", |
58 |
"backtracking due to slot conflict:", |
59 |
" first package: %s" % existing_node, |
60 |
- " package to mask: %s" % to_be_masked, |
61 |
+ " package(s) to mask: %s" % str(to_be_masked), |
62 |
" slot: %s" % slot_atom, |
63 |
" parents: %s" % ", ".join( |
64 |
"(%s, '%s')" % (ppkg, atom) for ppkg, atom in all_parents |
65 |
diff --git a/lib/_emerge/resolver/backtracking.py b/lib/_emerge/resolver/backtracking.py |
66 |
index bc3fb3206..ca94623ac 100644 |
67 |
--- a/lib/_emerge/resolver/backtracking.py |
68 |
+++ b/lib/_emerge/resolver/backtracking.py |
69 |
@@ -166,13 +166,14 @@ class Backtracker: |
70 |
self._feedback_slot_conflict(conflicts_data[0]) |
71 |
|
72 |
def _feedback_slot_conflict(self, conflict_data): |
73 |
- for pkg, parent_atoms in conflict_data: |
74 |
+ for similar_pkgs in conflict_data: |
75 |
new_node = copy.deepcopy(self._current_node) |
76 |
new_node.depth += 1 |
77 |
new_node.mask_steps += 1 |
78 |
new_node.terminal = False |
79 |
- new_node.parameter.runtime_pkg_mask.setdefault( |
80 |
- pkg, {})["slot conflict"] = parent_atoms |
81 |
+ for pkg, parent_atoms in similar_pkgs: |
82 |
+ new_node.parameter.runtime_pkg_mask.setdefault( |
83 |
+ pkg, {})["slot conflict"] = parent_atoms |
84 |
self._add(new_node) |
85 |
|
86 |
|
87 |
diff --git a/lib/portage/tests/resolver/test_slot_operator_missed_update.py b/lib/portage/tests/resolver/test_slot_operator_missed_update.py |
88 |
index 1ea701003..efad70615 100644 |
89 |
--- a/lib/portage/tests/resolver/test_slot_operator_missed_update.py |
90 |
+++ b/lib/portage/tests/resolver/test_slot_operator_missed_update.py |
91 |
@@ -90,7 +90,7 @@ class BacktrackMissedUpdateTestCase(TestCase): |
92 |
# Bug 743115: missed updates trigger excessive backtracking |
93 |
ResolverPlaygroundTestCase( |
94 |
[">=dev-python/pypy3-7.3.2_rc", "@world"], |
95 |
- options={"--update": True, "--deep": True, "--backtrack": 10}, |
96 |
+ options={"--update": True, "--deep": True, "--backtrack": 4}, |
97 |
success=True, |
98 |
mergelist=[ |
99 |
"dev-python/pypy3-7.3.2_rc2_p37-r1", |
100 |
-- |
101 |
2.25.3 |