Move deletion from dependency graph to __delitem__

Graph objects are mutable, and will in future be used for operations other
than a topological sort, so abstract out the code for deleting backlinks to
a node from the other nodes that have dependencies on it when it is
removed.

Change-Id: I86b81303ed2dffd969a2db10535761f108f4808a
This commit is contained in:
Zane Bitter 2013-05-28 10:16:37 +02:00
parent 0e31ec7e73
commit 1f0a9bc2d1
1 changed files with 18 additions and 16 deletions

View File

@ -110,6 +110,15 @@ class Graph(collections.defaultdict):
'''Return a copy of the graph with the edges reversed.'''
return Graph(self.map(lambda n: n.reverse_copy()))
def __delitem__(self, key):
'''Delete the node given by the specified key from the graph.'''
node = self[key]
for src in node.required_by():
self[src] -= key
return super(Graph, self).__delitem__(key)
def __str__(self):
'''Convert the graph to a human-readable string.'''
pairs = ('%s: %s' % (str(k), str(v)) for k, v in self.iteritems())
@ -122,23 +131,16 @@ class Graph(collections.defaultdict):
This is a destructive operation for the graph.
'''
def next_leaf():
for leaf, node in graph.iteritems():
if not node:
return leaf, node
# There are nodes remaining, but no more leaves: a cycle
raise CircularDependencyException(cycle=str(graph))
for iteration in xrange(len(graph)):
leaf, node = next_leaf()
yield leaf
# Remove the node and all edges connected to it before
# continuing to look for more leaves
for src in node.required_by():
graph[src] -= leaf
del graph[leaf]
for key, node in graph.iteritems():
if not node:
yield key
del graph[key]
break
else:
# There are nodes remaining, but none without
# dependencies: a cycle
raise CircularDependencyException(cycle=str(graph))
class Dependencies(object):