Gentoo Archives: gentoo-portage-dev

From: Sebastian Luther <SebastianLuther@×××.de>
To: gentoo-portage-dev@l.g.o
Subject: [gentoo-portage-dev] [PATCH 04/10] Replace _slot_collision_info with _package_tracker
Date: Wed, 29 Jan 2014 15:34:11
Message-Id: 1391009594-22750-5-git-send-email-SebastianLuther@gmx.de
In Reply to: [gentoo-portage-dev] [PATCH 00/10] First steps to get rid of backtracking by Sebastian Luther
1 ---
2 pym/_emerge/depgraph.py | 59 ++++++++++++----------------------
3 pym/_emerge/resolver/slot_collision.py | 22 ++++++-------
4 2 files changed, 31 insertions(+), 50 deletions(-)
5
6 diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py
7 index 9d234c2..484ac14 100644
8 --- a/pym/_emerge/depgraph.py
9 +++ b/pym/_emerge/depgraph.py
10 @@ -378,11 +378,6 @@ class _dynamic_depgraph_config(object):
11 # This use used to check if we have accounted for blockers
12 # relevant to a package.
13 self._traversed_pkg_deps = set()
14 - # This should be ordered such that the backtracker will
15 - # attempt to solve conflicts which occurred earlier first,
16 - # since an earlier conflict can be the cause of a conflict
17 - # which occurs later.
18 - self._slot_collision_info = OrderedDict()
19 # Slot collision nodes are not allowed to block other packages since
20 # blocker validation is only able to account for one package per slot.
21 self._slot_collision_nodes = set()
22 @@ -915,7 +910,7 @@ class depgraph(object):
23 cases.
24 """
25
26 - if not self._dynamic_config._slot_collision_info:
27 + if not any(self._dynamic_config._package_tracker.slot_conflicts()):
28 return
29
30 self._show_merge_list()
31 @@ -971,16 +966,18 @@ class depgraph(object):
32 is called, so that all relevant reverse dependencies are
33 available for use in backtracking decisions.
34 """
35 - for (slot_atom, root), slot_nodes in \
36 - self._dynamic_config._slot_collision_info.items():
37 - self._process_slot_conflict(root, slot_atom, slot_nodes)
38 + for conflict in self._dynamic_config._package_tracker.slot_conflicts():
39 + self._process_slot_conflict(conflict)
40
41 - def _process_slot_conflict(self, root, slot_atom, slot_nodes):
42 + def _process_slot_conflict(self, conflict):
43 """
44 Process slot conflict data to identify specific atoms which
45 lead to conflict. These atoms only match a subset of the
46 packages that have been pulled into a given slot.
47 """
48 + root = conflict.root
49 + slot_atom = conflict.atom
50 + slot_nodes = conflict.pkgs
51
52 debug = "--debug" in self._frozen_config.myopts
53
54 @@ -1999,7 +1996,6 @@ class depgraph(object):
55
56 existing_node, existing_node_matches = \
57 self._check_slot_conflict(pkg, dep.atom)
58 - slot_collision = False
59 if existing_node:
60 if existing_node_matches:
61 # The existing node can be reused.
62 @@ -2032,19 +2028,7 @@ class depgraph(object):
63 modified_use=self._pkg_use_enabled(existing_node))),
64 level=logging.DEBUG, noiselevel=-1)
65
66 - slot_collision = True
67 -
68 - if slot_collision:
69 - # Now add this node to the graph so that self.display()
70 - # can show use flags and --tree portage.output. This node is
71 - # only being partially added to the graph. It must not be
72 - # allowed to interfere with the other nodes that have been
73 - # added.
74 - # Even though the graph is now invalid, continue to process
75 - # dependencies so that things like --fetchonly can still
76 - # function despite collisions.
77 - pass
78 - elif not previously_added:
79 + if not previously_added:
80 self._dynamic_config._package_tracker.add_pkg(pkg)
81 self._dynamic_config._filtered_trees[pkg.root]["porttree"].dbapi._clear_cache()
82 self._dynamic_config._highest_pkg_cache.clear()
83 @@ -2156,14 +2140,6 @@ class depgraph(object):
84
85 def _add_slot_conflict(self, pkg):
86 self._dynamic_config._slot_collision_nodes.add(pkg)
87 - slot_key = (pkg.slot_atom, pkg.root)
88 - slot_nodes = self._dynamic_config._slot_collision_info.get(slot_key)
89 - if slot_nodes is None:
90 - slot_nodes = set()
91 - slot_nodes.update(self._dynamic_config._package_tracker.match(
92 - pkg.root, pkg.slot_atom, installed=False))
93 - self._dynamic_config._slot_collision_info[slot_key] = slot_nodes
94 - slot_nodes.add(pkg)
95
96 def _add_pkg_deps(self, pkg, allow_unsatisfied=False):
97
98 @@ -3284,7 +3260,8 @@ class depgraph(object):
99 except self._unknown_internal_error:
100 return False, myfavorites
101
102 - if (self._dynamic_config._slot_collision_info and
103 + have_slot_conflict = any(self._dynamic_config._package_tracker.slot_conflicts())
104 + if (have_slot_conflict and
105 not self._accept_blocker_conflicts()) or \
106 (self._dynamic_config._allow_backtracking and
107 "slot conflict" in self._dynamic_config._backtrack_infos):
108 @@ -6806,7 +6783,8 @@ class depgraph(object):
109 # conflicts (or by blind luck).
110 raise self._unknown_internal_error()
111
112 - if self._dynamic_config._slot_collision_info and \
113 + have_slot_conflict = any(self._dynamic_config._package_tracker.slot_conflicts())
114 + if have_slot_conflict and \
115 not self._accept_blocker_conflicts():
116 self._dynamic_config._serialized_tasks_cache = retlist
117 self._dynamic_config._scheduler_graph = scheduler_graph
118 @@ -6881,13 +6859,17 @@ class depgraph(object):
119 # the reasons are not apparent from the normal merge list
120 # display.
121
122 - slot_collision_info = self._dynamic_config._slot_collision_info
123 -
124 conflict_pkgs = {}
125 for blocker in blockers:
126 for pkg in chain(self._dynamic_config._blocked_pkgs.child_nodes(blocker), \
127 self._dynamic_config._blocker_parents.parent_nodes(blocker)):
128 - if (pkg.slot_atom, pkg.root) in slot_collision_info:
129 +
130 + is_slot_conflict_pkg = False
131 + for conflict in self._dynamic_config._package_tracker.slot_conflicts():
132 + if conflict.root == pkg.root and conflict.atom == pkg.slot_atom:
133 + is_slot_conflict_pkg = True
134 + break
135 + if is_slot_conflict_pkg:
136 # The slot conflict display has better noise reduction
137 # than the unsatisfied blockers display, so skip
138 # unsatisfied blockers display for packages involved
139 @@ -7370,7 +7352,8 @@ class depgraph(object):
140 self._dynamic_config._circular_deps_for_display)
141
142 unresolved_conflicts = False
143 - if self._dynamic_config._slot_collision_info:
144 + have_slot_conflict = any(self._dynamic_config._package_tracker.slot_conflicts())
145 + if have_slot_conflict:
146 unresolved_conflicts = True
147 self._show_slot_collision_notice()
148 if self._dynamic_config._unsatisfied_blockers_for_display is not None:
149 diff --git a/pym/_emerge/resolver/slot_collision.py b/pym/_emerge/resolver/slot_collision.py
150 index a193baa..ca3fb74 100644
151 --- a/pym/_emerge/resolver/slot_collision.py
152 +++ b/pym/_emerge/resolver/slot_collision.py
153 @@ -89,10 +89,11 @@ class slot_conflict_handler(object):
154 self.debug = "--debug" in self.myopts
155 if self.debug:
156 writemsg("Starting slot conflict handler\n", noiselevel=-1)
157 - #slot_collision_info is a dict mapping (slot atom, root) to set
158 - #of packages. The packages in the set all belong to the same
159 - #slot.
160 - self.slot_collision_info = depgraph._dynamic_config._slot_collision_info
161 +
162 + # List of tuples, where each tuple represents a slot conflict.
163 + self.all_conflicts = []
164 + for conflict in depgraph._dynamic_config._package_tracker.slot_conflicts():
165 + self.all_conflicts.append((conflict.root, conflict.atom, conflict.pkgs))
166
167 #A dict mapping packages to pairs of parent package
168 #and parent atom
169 @@ -109,8 +110,7 @@ class slot_conflict_handler(object):
170 all_conflict_atoms_by_slotatom = []
171
172 #fill conflict_pkgs, all_conflict_atoms_by_slotatom
173 - for (atom, root), pkgs \
174 - in self.slot_collision_info.items():
175 + for root, atom, pkgs in self.all_conflicts:
176 conflict_pkgs.append(list(pkgs))
177 all_conflict_atoms_by_slotatom.append(set())
178
179 @@ -249,8 +249,7 @@ class slot_conflict_handler(object):
180 msg.append("!!! into the dependency graph, resulting" + \
181 " in a slot conflict:\n\n")
182
183 - for (slot_atom, root), pkgs \
184 - in self.slot_collision_info.items():
185 + for root, slot_atom, pkgs in self.all_conflicts:
186 msg.append("%s" % (slot_atom,))
187 if root != self.depgraph._frozen_config._running_root.root:
188 msg.append(" for %s" % (root,))
189 @@ -536,13 +535,13 @@ class slot_conflict_handler(object):
190 return None
191
192 if len(solutions)==1:
193 - if len(self.slot_collision_info)==1:
194 + if len(self.all_conflicts) == 1:
195 msg += "It might be possible to solve this slot collision\n"
196 else:
197 msg += "It might be possible to solve these slot collisions\n"
198 msg += "by applying all of the following changes:\n"
199 else:
200 - if len(self.slot_collision_info)==1:
201 + if len(self.all_conflicts) == 1:
202 msg += "It might be possible to solve this slot collision\n"
203 else:
204 msg += "It might be possible to solve these slot collisions\n"
205 @@ -583,8 +582,7 @@ class slot_conflict_handler(object):
206 if not pkg.installed:
207 continue
208
209 - for (atom, root), pkgs \
210 - in self.slot_collision_info.items():
211 + for root, atom, pkgs in self.all_conflicts:
212 if pkg not in pkgs:
213 continue
214 for other_pkg in pkgs:
215 --
216 1.8.3.2