Fix depgraph.altlist() so that it can identify a group of nodes that completely satis...
authorZac Medico <zmedico@gentoo.org>
Mon, 2 Oct 2006 22:08:04 +0000 (22:08 -0000)
committerZac Medico <zmedico@gentoo.org>
Mon, 2 Oct 2006 22:08:04 +0000 (22:08 -0000)
svn path=/main/trunk/; revision=4572

bin/emerge
pym/portage.py

index 08c43b5798b39318ddf4d1707ab397035af21006..ca34683a824f5b1ba91101426b479a29f86af246 100755 (executable)
@@ -1256,26 +1256,56 @@ class depgraph:
                mygraph=self.digraph.copy()
                retlist=[]
                while not mygraph.empty():
+                       ignore_priority = -1
                        if reversed:
                                nodes = mygraph.root_nodes()
                                if not nodes:
+                                       ignore_priority = digraph.SOFT
                                        nodes = mygraph.root_nodes(ignore_priority=digraph.SOFT)
                                if not nodes:
+                                       ignore_priority = digraph.MEDIUM
                                        nodes = mygraph.root_nodes(ignore_priority=digraph.MEDIUM)
                        else:
                                nodes = mygraph.leaf_nodes()
                                if not nodes:
+                                       ignore_priority = digraph.SOFT
                                        nodes = mygraph.leaf_nodes(ignore_priority=digraph.SOFT)
                                if not nodes:
+                                       ignore_priority = digraph.MEDIUM
                                        nodes = mygraph.leaf_nodes(ignore_priority=digraph.MEDIUM)
-                       if not nodes:
+
+                       selected_nodes = None
+                       if nodes:
+                               if ignore_priority <= digraph.SOFT or len(nodes) == 1:
+                                       selected_nodes = [nodes[0]]
+                               else:
+                                       """Find two or more nodes that are mutually dependent and
+                                       completely satisfy eachother's non-soft deps."""
+                                       nodes = set(nodes)
+                                       selected_nodes = None
+                                       for node in nodes:
+                                               selected_nodes = set(mygraph.child_nodes(node,
+                                                       ignore_priority=digraph.SOFT))
+                                               selected_nodes.add(node)
+                                               grandchildren = set()
+                                               for child in mygraph.child_nodes(node,
+                                                       ignore_priority=digraph.SOFT):
+                                                       grandchildren.update(mygraph.child_nodes(child,
+                                                               ignore_priority=digraph.SOFT))
+                                               if grandchildren.issubset(selected_nodes):
+                                                       break
+                                               selected_nodes = None
+
+                       if not selected_nodes:
                                print "!!! Error: circular dependencies:"
                                print
                                mygraph.debug_print()
                                sys.exit(1)
-                       for node in nodes:
+
+                       for node in selected_nodes:
                                retlist.append(node.split())
                                mygraph.remove(node)
+
                return retlist
 
        def xcreate(self,mode="system"):
index f3de6d9e3b61713f3bb8f56401b68bf6b3c0c06d..620ef06bd298346003ff2d6970f7b2a2b55eb3d7 100644 (file)
@@ -375,9 +375,15 @@ class digraph:
                """Return a list of all nodes in the graph"""
                return self.order[:]
 
-       def child_nodes(self, node):
+       def child_nodes(self, node, ignore_priority=-1):
                """Return all children of the specified node"""
-               return self.nodes[node][0].keys()
+               if ignore_priority == -1:
+                       return self.nodes[node][0].keys()
+               children = []
+               for child, priority in self.nodes[node][0].iteritems():
+                       if priority > ignore_priority:
+                               children.append(child)
+               return children
 
        def parent_nodes(self, node):
                """Return all parents of the specified node"""