~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tsort.py

  • Committer: John Arbash Meinel
  • Date: 2009-08-17 18:36:14 UTC
  • mto: This revision was merged to the branch mainline in revision 4629.
  • Revision ID: john@arbash-meinel.com-20090817183614-ss5shqo00p002imm
Move the topo_sort implementation into KnownGraph, rather than calling back to it.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
"""Topological sorting routines."""
19
19
 
20
20
 
21
 
from bzrlib import errors
22
 
import bzrlib.revision as _mod_revision
 
21
from bzrlib import (
 
22
    errors,
 
23
    graph as _mod_graph,
 
24
    revision as _mod_revision,
 
25
    )
23
26
from collections import deque
24
27
 
25
28
 
44
47
    topo_sort is faster when the whole list is needed, while when iterating
45
48
    over a part of the list, TopoSorter.iter_topo_order should be used.
46
49
    """
47
 
    # store a dict of the graph.
48
 
    graph = dict(graph)
49
 
    # this is the stack storing on which the sorted nodes are pushed.
50
 
    node_stack = []
51
 
 
52
 
    # count the number of children for every node in the graph
53
 
    node_child_count = dict.fromkeys(graph.iterkeys(), 0)
54
 
    for parents in graph.itervalues():
55
 
        for parent in parents:
56
 
            # don't count the parent if it's a ghost
57
 
            if parent in node_child_count:
58
 
                node_child_count[parent] += 1
59
 
    # keep track of nodes without children in a separate list
60
 
    nochild_nodes = deque([node for (node, n) in node_child_count.iteritems()
61
 
                                 if n == 0])
62
 
 
63
 
    graph_pop = graph.pop
64
 
    node_stack_append = node_stack.append
65
 
    nochild_nodes_pop = nochild_nodes.pop
66
 
    nochild_nodes_append = nochild_nodes.append
67
 
 
68
 
    while nochild_nodes:
69
 
        # pick a node without a child and add it to the stack.
70
 
        node_name = nochild_nodes_pop()
71
 
        node_stack_append(node_name)
72
 
 
73
 
        # the parents of the node lose it as a child; if it was the last
74
 
        # child, add the parent to the list of childless nodes.
75
 
        parents = graph_pop(node_name)
76
 
        for parent in parents:
77
 
            if parent in node_child_count:
78
 
                node_child_count[parent] -= 1
79
 
                if node_child_count[parent] == 0:
80
 
                    nochild_nodes_append(parent)
81
 
 
82
 
    # if there are still nodes left in the graph,
83
 
    # that means that there is a cycle
84
 
    if graph:
85
 
        raise errors.GraphCycleError(graph)
86
 
 
87
 
    # the nodes where pushed on the stack child first, so this list needs to be
88
 
    # reversed before returning it.
89
 
    node_stack.reverse()
90
 
    return node_stack
 
50
    kg = _mod_graph.KnownGraph(graph)
 
51
    return kg.topo_sort()
91
52
 
92
53
 
93
54
class TopoSorter(object):