From: Zac Medico Date: Wed, 11 Mar 2009 05:08:15 +0000 (-0000) Subject: In depgraph._serialize_tasks(), verify that an uninstall task has at least one X-Git-Tag: v2.1.6.8~191 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=f4872aef58113e30b1f681d4b0e4c57511ecea8b;p=portage.git In depgraph._serialize_tasks(), verify that an uninstall task has at least one theoretically mergeable parent before choosing to reverse it's edges. (trunk r12605) svn path=/main/branches/2.1.6/; revision=12886 --- diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index 61a41529d..4109322f9 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -6846,6 +6846,41 @@ class depgraph(object): runtime_deps.update(atom for atom in portage_rdepend \ if not atom.startswith("!")) + def gather_deps(ignore_priority, mergeable_nodes, + selected_nodes, node): + """ + Recursively gather a group of nodes that RDEPEND on + eachother. This ensures that they are merged as a group + and get their RDEPENDs satisfied as soon as possible. + """ + if node in selected_nodes: + return True + if node not in mergeable_nodes: + return False + if node == replacement_portage and \ + mygraph.child_nodes(node, + ignore_priority=DepPriority.MEDIUM_SOFT): + # Make sure that portage always has all of it's + # RDEPENDs installed first. + return False + selected_nodes.add(node) + for child in mygraph.child_nodes(node, + ignore_priority=ignore_priority): + if not gather_deps(ignore_priority, + mergeable_nodes, selected_nodes, child): + return False + return True + + def ignore_uninst_or_med(priority): + if priority is BlockerDepPriority.instance: + return True + return priority <= DepPriority.MEDIUM + + def ignore_uninst_or_med_soft(priority): + if priority is BlockerDepPriority.instance: + return True + return priority <= DepPriority.MEDIUM_SOFT + ignore_priority_soft_range = [None] ignore_priority_soft_range.extend( xrange(DepPriority.MIN, DepPriority.MEDIUM_SOFT + 1)) @@ -6924,28 +6959,6 @@ class depgraph(object): if not selected_nodes: nodes = get_nodes(ignore_priority=DepPriority.MEDIUM) if nodes: - """Recursively gather a group of nodes that RDEPEND on - eachother. This ensures that they are merged as a group - and get their RDEPENDs satisfied as soon as possible.""" - def gather_deps(ignore_priority, - mergeable_nodes, selected_nodes, node): - if node in selected_nodes: - return True - if node not in mergeable_nodes: - return False - if node == replacement_portage and \ - mygraph.child_nodes(node, - ignore_priority=DepPriority.MEDIUM_SOFT): - # Make sure that portage always has all of it's - # RDEPENDs installed first. - return False - selected_nodes.add(node) - for child in mygraph.child_nodes(node, - ignore_priority=ignore_priority): - if not gather_deps(ignore_priority, - mergeable_nodes, selected_nodes, child): - return False - return True mergeable_nodes = set(nodes) if prefer_asap and asap_nodes: nodes = asap_nodes @@ -7003,6 +7016,10 @@ class depgraph(object): if not selected_nodes and not myblocker_uninstalls.is_empty(): # An Uninstall task needs to be executed in order to # avoid conflict if possible. + + mergeable_nodes = get_nodes( + ignore_priority=ignore_uninst_or_med) + min_parent_deps = None uninst_task = None for task in myblocker_uninstalls.leaf_nodes(): @@ -7128,10 +7145,19 @@ class depgraph(object): # best possible choice, but the current algorithm # is simple and should be near optimal for most # common cases. + mergeable_parent = False parent_deps = set() for parent in mygraph.parent_nodes(task): parent_deps.update(mygraph.child_nodes(parent, ignore_priority=DepPriority.MEDIUM_SOFT)) + if parent in mergeable_nodes and \ + gather_deps(ignore_uninst_or_med_soft, + mergeable_nodes, set(), parent): + mergeable_parent = True + + if not mergeable_parent: + continue + parent_deps.remove(task) if min_parent_deps is None or \ len(parent_deps) < min_parent_deps: