From: Zac Medico Date: Wed, 5 Sep 2007 23:09:21 +0000 (-0000) Subject: In the topological sort for merge order, try to avoid selecting root nodes X-Git-Tag: v2.2_pre1~831 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=6df0b0f6bf116d920fe3a98933340dfe52a33280;p=portage.git In the topological sort for merge order, 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 been 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). With this patch, `emerge -e system` properly rebuilds dev-lang/python before sys-apps/file, which helps to avoid a potential build failure. svn path=/main/trunk/; revision=7728 --- diff --git a/pym/emerge/__init__.py b/pym/emerge/__init__.py index 8354da39f..2550da4c4 100644 --- a/pym/emerge/__init__.py +++ b/pym/emerge/__init__.py @@ -2246,6 +2246,26 @@ class depgraph(object): # failed to select any nodes. It is reset whenever nodes are # 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. + # + # iteration prefer_asap accept_root_node + # 1 True False + # 2 False False + # 3 False True + # + # If no nodes are selected on the 4th iteration, it is due to + # unresolved blockers or circular dependencies. + while not mygraph.empty(): selected_nodes = None if prefer_asap and asap_nodes: @@ -2280,7 +2300,8 @@ class depgraph(object): # found a non-root node selected_nodes = [node] break - if not selected_nodes: + if not selected_nodes and \ + (accept_root_node or ignore_priority is None): # settle for a root node selected_nodes = [nodes[0]] if not selected_nodes: @@ -2313,6 +2334,9 @@ class depgraph(object): for ignore_priority in xrange(DepPriority.SOFT, DepPriority.MEDIUM_SOFT + 1): for node in nodes: + if not accept_root_node and \ + not mygraph.parent_nodes(node): + continue selected_nodes = set() if gather_deps(ignore_priority, mergeable_nodes, selected_nodes, node): @@ -2328,6 +2352,12 @@ 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: @@ -2408,8 +2438,10 @@ class depgraph(object): sys.exit(1) # At this point, we've succeeded in selecting one or more nodes, so - # it's now safe to reset the prefer_asap to it's default state. + # it's now safe to reset the prefer_asap and accept_root_node flags + # to their default states. prefer_asap = True + accept_root_node = False for node in selected_nodes: if node[-1] != "nomerge":