~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/_known_graph_py.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2009-08-19 18:04:49 UTC
  • mfrom: (4593.5.43 1.19-known-graph-sorted)
  • Revision ID: pqm@pqm.ubuntu.com-20090819180449-p5dibldf9pcp24n4
(jam) Add VersionedFiles.get_known_graph_ancestry and
        KnownGraph.merge_sort()

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
"""
19
19
 
20
20
from bzrlib import (
 
21
    errors,
21
22
    revision,
22
23
    )
23
24
 
40
41
            self.parent_keys, self.child_keys)
41
42
 
42
43
 
 
44
class _MergeSortNode(object):
 
45
    """Information about a specific node in the merge graph."""
 
46
 
 
47
    __slots__ = ('key', 'merge_depth', 'revno', 'end_of_merge')
 
48
 
 
49
    def __init__(self, key, merge_depth, revno, end_of_merge):
 
50
        self.key = key
 
51
        self.merge_depth = merge_depth
 
52
        self.revno = revno
 
53
        self.end_of_merge = end_of_merge
 
54
 
 
55
 
43
56
class KnownGraph(object):
44
57
    """This is a class which assumes we already know the full graph."""
45
58
 
171
184
            self._known_heads[heads_key] = heads
172
185
        return heads
173
186
 
 
187
    def topo_sort(self):
 
188
        """Return the nodes in topological order.
 
189
 
 
190
        All parents must occur before all children.
 
191
        """
 
192
        for node in self._nodes.itervalues():
 
193
            if node.gdfo is None:
 
194
                raise errors.GraphCycleError(self._nodes)
 
195
        pending = self._find_tails()
 
196
        pending_pop = pending.pop
 
197
        pending_append = pending.append
 
198
 
 
199
        topo_order = []
 
200
        topo_order_append = topo_order.append
 
201
 
 
202
        num_seen_parents = dict.fromkeys(self._nodes, 0)
 
203
        while pending:
 
204
            node = pending_pop()
 
205
            if node.parent_keys is not None:
 
206
                # We don't include ghost parents
 
207
                topo_order_append(node.key)
 
208
            for child_key in node.child_keys:
 
209
                child_node = self._nodes[child_key]
 
210
                seen_parents = num_seen_parents[child_key] + 1
 
211
                if seen_parents == len(child_node.parent_keys):
 
212
                    # All parents have been processed, enqueue this child
 
213
                    pending_append(child_node)
 
214
                    # This has been queued up, stop tracking it
 
215
                    del num_seen_parents[child_key]
 
216
                else:
 
217
                    num_seen_parents[child_key] = seen_parents
 
218
        # We started from the parents, so we don't need to do anymore work
 
219
        return topo_order
 
220
 
 
221
    def merge_sort(self, tip_key):
 
222
        """Compute the merge sorted graph output."""
 
223
        from bzrlib import tsort
 
224
        as_parent_map = dict((node.key, node.parent_keys)
 
225
                             for node in self._nodes.itervalues()
 
226
                              if node.parent_keys is not None)
 
227
        # We intentionally always generate revnos and never force the
 
228
        # mainline_revisions
 
229
        # Strip the sequence_number that merge_sort generates
 
230
        return [_MergeSortNode(key, merge_depth, revno, end_of_merge)
 
231
                for _, key, merge_depth, revno, end_of_merge
 
232
                 in tsort.merge_sort(as_parent_map, tip_key,
 
233
                                     mainline_revisions=None,
 
234
                                     generate_revno=True)]