/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/graph.py

  • Committer: Aaron Bentley
  • Date: 2005-09-10 23:46:35 UTC
  • mto: (1185.3.4)
  • mto: This revision was merged to the branch mainline in revision 1390.
  • Revision ID: aaron.bentley@utoronto.ca-20050910234635-2586547c19f8c4cc
Updated name to farthest_nodes

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
        
 
2
def max_distance(node, ancestors, distances):
 
3
    """Calculate the max distance to an ancestor.  
 
4
    Return None if not all possible ancestors have known distances"""
 
5
    best = None
 
6
    if node in distances:
 
7
        best = distances[node]
 
8
    for ancestor in ancestors[node]:
 
9
        # An ancestor which is not listed in ancestors will never be in
 
10
        # distances, so we pretend it never existed.
 
11
        if ancestor not in ancestors:
 
12
            continue
 
13
        if ancestor not in distances:
 
14
            return None
 
15
        if best is None or distances[ancestor] > best:
 
16
            best = distances[ancestor] + 1
 
17
    return best
 
18
 
 
19
    
 
20
def farthest_nodes(graph, ancestors, start):
 
21
    """Produce a list of nodes, sorted by distance from a start node.
 
22
    This is an algorithm devised by Aaron Bentley, because applying Dijkstra
 
23
    backwards seemed too complicated.
 
24
 
 
25
    For each node, we walk its descendants.  If all the descendant's ancestors
 
26
    have a max-distance-to-start, (excluding ones that can never reach start),
 
27
    we calculate their max-distance-to-start, and schedule their descendants.
 
28
 
 
29
    So when a node's last parent acquires a distance, it will acquire a
 
30
    distance on the next iteration.
 
31
 
 
32
    Once we know the max distances for all nodes, we can return a list sorted
 
33
    by distance, farthest first.
 
34
    """
 
35
    distances = {start: 0}
 
36
    lines = set([start])
 
37
    while len(lines) > 0:
 
38
        new_lines = set()
 
39
        for line in lines:
 
40
            assert line not in graph[line], "%s refers to itself" % line
 
41
            for descendant in graph[line]:
 
42
                distance = max_distance(descendant, ancestors, distances)
 
43
                if distance is None:
 
44
                    continue
 
45
                distances[descendant] = distance
 
46
                new_lines.add(descendant)
 
47
        lines = new_lines
 
48
 
 
49
    def by_distance(n):
 
50
        return distances[n],n
 
51
    node_list = distances.keys()
 
52
    node_list.sort(key=by_distance, reverse=True)
 
53
    return node_list