Gentoo Archives: gentoo-portage-dev

From: Zac Medico <zmedico@g.o>
To: gentoo-portage-dev@l.g.o
Cc: Zac Medico <zmedico@g.o>
Subject: [gentoo-portage-dev] [PATCH] _slot_confict_backtrack: group similar missed updates (bug 743115)
Date: Sat, 19 Sep 2020 23:44:57
Message-Id: 20200919234211.345289-1-zmedico@gentoo.org
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