From 96a7f2628cbd71c9747f321f29e7f1a0247d94af Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Wed, 11 Mar 2009 03:44:00 +0000 Subject: [PATCH] Inside depgraph._serialize_tasks(), simplify the logic which delays selection of root nodes. (trunk r12585) svn path=/main/branches/2.1.6/; revision=12866 --- pym/_emerge/__init__.py | 90 ++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 51 deletions(-) diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index 95409e372..d7cce1e74 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -6848,23 +6848,14 @@ class depgraph(object): # successfully selected. prefer_asap = True - # By default, try to avoid selecting root nodes whenever possible. This - # helps ensure that the maximimum possible number of soft dependencies - # have been removed from the graph before their parent nodes have - # selected. This is especially important when those dependencies are - # going to be rebuilt by revdep-rebuild or `emerge -e system` after the - # CHOST has been changed (like when building a stage3 from a stage2). - accept_root_node = False - - # State of prefer_asap and accept_root_node flags for successive - # iterations that loosen the criteria for node selection. + # State of variables for successive iterations that loosen the + # criteria for node selection. # - # iteration prefer_asap accept_root_node - # 1 True False - # 2 False False - # 3 False True + # iteration prefer_asap + # 1 True + # 2 False # - # If no nodes are selected on the 3rd iteration, it is due to + # If no nodes are selected on the last iteration, it is due to # unresolved blockers or circular dependencies. while not mygraph.empty(): @@ -6872,7 +6863,9 @@ class depgraph(object): selected_nodes = None ignore_priority = None if prefer_asap and asap_nodes: - """ASAP nodes are merged before their soft deps.""" + # ASAP nodes are merged before their soft deps. Go ahead and + # select root nodes here if necessary, since it's typical for + # the parent to have been removed from the graph already. asap_nodes = [node for node in asap_nodes \ if mygraph.contains(node)] for node in asap_nodes: @@ -6916,10 +6909,7 @@ class depgraph(object): # found a non-root node selected_nodes = [node] break - if not selected_nodes and \ - (accept_root_node or ignore_priority is None): - # settle for a root node - selected_nodes = [nodes[0]] + if selected_nodes: break @@ -6954,9 +6944,7 @@ class depgraph(object): for ignore_priority in xrange(DepPriority.SOFT, DepPriority.MEDIUM_SOFT + 1): for node in nodes: - if nodes is not asap_nodes and \ - not accept_root_node and \ - not mygraph.parent_nodes(node): + if not mygraph.parent_nodes(node): continue selected_nodes = set() if gather_deps(ignore_priority, @@ -6981,12 +6969,6 @@ class depgraph(object): prefer_asap = False continue - if not selected_nodes and not accept_root_node: - # Maybe there are only root nodes left, so accept them - # for the next iteration. - accept_root_node = True - continue - if selected_nodes and ignore_priority > DepPriority.SOFT: # Try to merge ignored medium deps as soon as possible. for node in selected_nodes: @@ -7167,29 +7149,37 @@ class depgraph(object): scheduler_graph.add(blocked_pkg, uninst_task, priority=BlockerDepPriority.instance) - else: - # None of the Uninstall tasks are acceptable, so - # the corresponding blockers are unresolvable. - # We need to drop an Uninstall task here in order - # to avoid the circular deps code path, but the - # blocker will still be counted as an unresolved - # conflict. - for node in myblocker_uninstalls.leaf_nodes(): - try: - mygraph.remove(node) - except KeyError: - pass - else: - uninst_task = node - ignored_uninstall_tasks.add(node) - break + # Reset the state variables for leaf node selection and + # continue trying to select leaf nodes. + prefer_asap = True + continue + + if not selected_nodes: + # Only select root nodes as a last resort. This case should + # only trigger when the graph is nearly empty and the only + # remaining nodes are isolated (no parents or children). Since + # the nodes must be isolated, ignore_priority is not needed. + selected_nodes = get_nodes() + + if not selected_nodes and not myblocker_uninstalls.is_empty(): + # If possible, drop an uninstall task here in order to avoid + # the circular deps code path. The corresponding blocker will + # still be counted as an unresolved conflict. + uninst_task = None + for node in myblocker_uninstalls.leaf_nodes(): + try: + mygraph.remove(node) + except KeyError: + pass + else: + uninst_task = node + ignored_uninstall_tasks.add(node) + break if uninst_task is not None: - # After dropping an Uninstall task, reset - # the state variables for leaf node selection and + # Reset the state variables for leaf node selection and # continue trying to select leaf nodes. prefer_asap = True - accept_root_node = False continue if not selected_nodes: @@ -7197,10 +7187,8 @@ class depgraph(object): raise self._unknown_internal_error() # At this point, we've succeeded in selecting one or more nodes, so - # it's now safe to reset the prefer_asap and accept_root_node flags - # to their default states. + # reset state variables for leaf node selection. prefer_asap = True - accept_root_node = False mygraph.difference_update(selected_nodes) -- 2.26.2