Optimize the new --skipfirst code so that in only has to build
authorZac Medico <zmedico@gentoo.org>
Sat, 31 May 2008 01:54:11 +0000 (01:54 -0000)
committerZac Medico <zmedico@gentoo.org>
Sat, 31 May 2008 01:54:11 +0000 (01:54 -0000)
a new depgraph one time when there are unsatisfied deps. This
works by recursively traversing the digraph to remove the parent
packages whose deps become unsatisfied when their dependencies are
pruned from the mergelist.

svn path=/main/trunk/; revision=10513

pym/_emerge/__init__.py

index dd80c16d27a63172f0ef679219cd00285e5b9b3e..8ae31e50c32208797fa3ea240661deea874d410c 100644 (file)
@@ -8369,18 +8369,47 @@ def action_build(settings, trees, mtimedb,
                        while True:
                                mydepgraph = depgraph(settings, trees,
                                        myopts, myparams, spinner)
+                               graph = mydepgraph.digraph
                                try:
                                        success = mydepgraph.loadResumeCommand(mtimedb["resume"])
                                except depgraph.UnsatisfiedResumeDep, e:
                                        if "--skipfirst" not in myopts:
                                                raise
-                                       unsatisfied_parents = set(dep.parent for dep in e.value)
-                                       pruned_mergelist = []
-                                       for task in mergelist:
-                                               if isinstance(task, list) and \
-                                                       tuple(task) in unsatisfied_parents:
+
+                                       unsatisfied_parents = dict((dep.parent, dep.parent) \
+                                               for dep in e.value)
+                                       traversed_nodes = set()
+                                       unsatisfied_stack = list(unsatisfied_parents)
+                                       while unsatisfied_stack:
+                                               pkg = unsatisfied_stack.pop()
+                                               if pkg in traversed_nodes:
                                                        continue
-                                               pruned_mergelist.append(task)
+                                               traversed_nodes.add(pkg)
+
+                                               # If this package was pulled in by a parent
+                                               # package scheduled for merge, removing this
+                                               # package may cause the the parent package's
+                                               # dependency to become unsatisfied.
+                                               for parent_node in graph.parent_nodes(pkg):
+                                                       if not isinstance(parent_node, Package) \
+                                                               or parent_node.operation != "merge":
+                                                               continue
+                                                       unsatisfied = \
+                                                               graph.child_nodes(parent_node,
+                                                               ignore_priority=DepPriority.SOFT)
+                                                       if pkg in unsatisfied:
+                                                               unsatisfied_parents[parent_node] = parent_node
+                                                               unsatisfied_stack.append(parent_node)
+
+                                       pruned_mergelist = [x for x in mergelist \
+                                               if isinstance(x, list) and \
+                                               tuple(x) not in unsatisfied_parents]
+
+                                       # It shouldn't happen, but if the size of mergelist
+                                       # does not decrease for some reason then the loop
+                                       # will be infinite. Therefore, if that case ever
+                                       # occurs for some reason, raise the exception to
+                                       # break out of the loop.
                                        if not pruned_mergelist or \
                                                len(pruned_mergelist) == len(mergelist):
                                                raise