summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2008-05-31 02:08:25 +0000
committerZac Medico <zmedico@gentoo.org>2008-05-31 02:08:25 +0000
commitfecc6af2264ea2d62121bc545fe7817c26956058 (patch)
tree55f215f793b3f4633b353d9e4e344fa0e025e53e
parentFix PackageSet.findAtomForPackage() to find the most specific atom since (diff)
downloadportage-multirepo-fecc6af2264ea2d62121bc545fe7817c26956058.tar.gz
portage-multirepo-fecc6af2264ea2d62121bc545fe7817c26956058.tar.bz2
portage-multirepo-fecc6af2264ea2d62121bc545fe7817c26956058.zip
Optimize the new --skipfirst code so that in only has to build
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. (trunk r10512:10514) svn path=/main/branches/2.1.2/; revision=10515
-rwxr-xr-xbin/emerge44
1 files changed, 37 insertions, 7 deletions
diff --git a/bin/emerge b/bin/emerge
index 72955612..a1761e7e 100755
--- a/bin/emerge
+++ b/bin/emerge
@@ -8314,19 +8314,49 @@ def action_build(settings, trees, mtimedb,
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:
+
+ graph = mydepgraph.digraph
+ 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
mergelist[:] = pruned_mergelist
dropped_tasks.update(unsatisfied_parents)
- del e, unsatisfied_parents
+ del e, graph, traversed_nodes, \
+ unsatisfied_parents, unsatisfied_stack
continue
else:
break