~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/graph.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2007-09-05 00:16:48 UTC
  • mfrom: (2776.1.6 commit)
  • Revision ID: pqm@pqm.ubuntu.com-20070905001648-0iigag4tq1u8mywn
(robertc) Deprecated find_previous_heads and add Graph.heads detangling some of the inventory related commit code. (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
134
134
           ancestor of all border ancestors.
135
135
        """
136
136
        border_common, common, sides = self._find_border_ancestors(revisions)
137
 
        return self._filter_candidate_lca(border_common)
 
137
        # We may have common ancestors that can be reached from each other.
 
138
        # - ask for the heads of them to filter it down to only ones that
 
139
        # cannot be reached from each other - phase 2.
 
140
        return self.heads(border_common)
138
141
 
139
142
    def find_difference(self, left_revision, right_revision):
140
143
        """Determine the graph difference between two revisions"""
212
215
                    for searcher in searchers:
213
216
                        update_common(searcher, revision)
214
217
 
215
 
    def _filter_candidate_lca(self, candidate_lca):
216
 
        """Remove candidates which are ancestors of other candidates.
217
 
 
218
 
        This is done by searching the ancestries of each border ancestor.  It
219
 
        is perfomed on the principle that a border ancestor that is not an
220
 
        ancestor of any other border ancestor is a lowest common ancestor.
221
 
 
222
 
        Searches are stopped when they find a node that is determined to be a
223
 
        common ancestor of all border ancestors, because this shows that it
224
 
        cannot be a descendant of any border ancestor.
225
 
 
226
 
        This will scale with the number of candidate ancestors and the length
227
 
        of the shortest path from a candidate to an ancestor common to all
228
 
        candidates.
 
218
    def heads(self, keys):
 
219
        """Return the heads from amongst keys.
 
220
 
 
221
        This is done by searching the ancestries of each key.  Any key that is
 
222
        reachable from another key is not returned; all the others are.
 
223
 
 
224
        This operation scales with the relative depth between any two keys. If
 
225
        any two keys are completely disconnected all ancestry of both sides
 
226
        will be retrieved.
 
227
 
 
228
        :param keys: An iterable of keys.
 
229
        :return: A set of the heads. Note that as a set there is no ordering
 
230
            information. Callers will need to filter their input to create
 
231
            order if they need it.
229
232
        """
 
233
        candidate_heads = set(keys)
230
234
        searchers = dict((c, self._make_breadth_first_searcher([c]))
231
 
                          for c in candidate_lca)
 
235
                          for c in candidate_heads)
232
236
        active_searchers = dict(searchers)
233
237
        # skip over the actual candidate for each searcher
234
238
        for searcher in active_searchers.itervalues():
248
252
                    del active_searchers[candidate]
249
253
                    continue
250
254
                for ancestor in ancestors:
251
 
                    if ancestor in candidate_lca:
252
 
                        candidate_lca.remove(ancestor)
 
255
                    if ancestor in candidate_heads:
 
256
                        candidate_heads.remove(ancestor)
253
257
                        del searchers[ancestor]
254
258
                        if ancestor in active_searchers:
255
259
                            del active_searchers[ancestor]
264
268
                            seen_ancestors =\
265
269
                                searcher.find_seen_ancestors(ancestor)
266
270
                            searcher.stop_searching_any(seen_ancestors)
267
 
        return candidate_lca
 
271
        return candidate_heads
268
272
 
269
273
    def find_unique_lca(self, left_revision, right_revision):
270
274
        """Find a unique LCA.