Rev 3192: * ``InterRepository.missing_revision_ids`` is now deprecated in favour of in http://people.ubuntu.com/~robertc/baz2.0/search-results

Robert Collins robertc at robertcollins.net
Thu Jan 17 03:15:58 GMT 2008


At http://people.ubuntu.com/~robertc/baz2.0/search-results

------------------------------------------------------------
revno: 3192
revision-id:robertc at robertcollins.net-20080117031420-zrmkezusngok2437
parent: robertc at robertcollins.net-20080116012748-anci5pui3pdx9ypy
committer: Robert Collins <robertc at robertcollins.net>
branch nick: use-SearchResult
timestamp: Thu 2008-01-17 14:14:20 +1100
message:
   * ``InterRepository.missing_revision_ids`` is now deprecated in favour of
     ``InterRepository.search_missing_revision_ids`` which returns a 
     ``bzrlib.graph.SearchResult`` suitable for making requests from the smart
     server. (Robert Collins)
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/fetch.py                fetch.py-20050818234941-26fea6105696365d
  bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
  bzrlib/symbol_versioning.py    symbol_versioning.py-20060105104851-9ecf8af605d15a80
  bzrlib/tests/interrepository_implementations/test_interrepository.py test_interrepository.py-20060220061411-1ec13fa99e5e3eee
=== modified file 'NEWS'
--- a/NEWS	2008-01-16 01:27:48 +0000
+++ b/NEWS	2008-01-17 03:14:20 +0000
@@ -181,6 +181,11 @@
 
    * get_parent_map now always provides tuples as its output.  (Aaron Bentley)
 
+   * ``InterRepository.missing_revision_ids`` is now deprecated in favour of
+     ``InterRepository.search_missing_revision_ids`` which returns a 
+     ``bzrlib.graph.SearchResult`` suitable for making requests from the smart
+     server. (Robert Collins)
+
    * New method ``iter_inventories`` on Repository for access to many
      inventories. This is primarily used by the ``revision_trees`` method, as
      direct access to inventories is discouraged. (Robert Collins)

=== modified file 'bzrlib/fetch.py'
--- a/bzrlib/fetch.py	2008-01-14 05:16:07 +0000
+++ b/bzrlib/fetch.py	2008-01-17 03:14:20 +0000
@@ -33,8 +33,8 @@
 
 import bzrlib
 import bzrlib.errors as errors
-from bzrlib.errors import (InstallFailed,
-                           )
+from bzrlib.errors import InstallFailed
+from bzrlib.graph import SearchResult
 from bzrlib.progress import ProgressPhase
 from bzrlib.revision import is_null, NULL_REVISION
 from bzrlib.symbol_versioning import (deprecated_function,
@@ -133,8 +133,8 @@
         pp = ProgressPhase('Transferring', 4, self.pb)
         try:
             pp.next_phase()
-            revs = self._revids_to_fetch()
-            if revs is None:
+            revs = self._revids_to_fetch().get_keys()
+            if not revs:
                 return
             self._fetch_everything_for_revisions(revs, pp)
         finally:
@@ -194,16 +194,14 @@
         mutter('fetch up to rev {%s}', self._last_revision)
         if self._last_revision is NULL_REVISION:
             # explicit limit of no revisions needed
-            return None
+            return SearchResult(set(), set(), 0, set())
         if (self._last_revision is not None and
             self.to_repository.has_revision(self._last_revision)):
-            return None
-            
+            return SearchResult(set(), set(), 0, set())
         try:
-            # XXX: this gets the full graph on both sides, and will make sure
-            # that ghosts are filled whether or not you care about them.
-            return self.to_repository.missing_revision_ids(self.from_repository,
-                self._last_revision, find_ghosts=self.find_ghosts)
+            return self.to_repository.search_missing_revision_ids(
+                self.from_repository, self._last_revision,
+                find_ghosts=self.find_ghosts)
         except errors.NoSuchRevision:
             raise InstallFailed([self._last_revision])
 

=== modified file 'bzrlib/repository.py'
--- a/bzrlib/repository.py	2008-01-14 05:16:07 +0000
+++ b/bzrlib/repository.py	2008-01-17 03:14:20 +0000
@@ -852,6 +852,18 @@
                 (format, data_list, reader_func))
 
     @needs_read_lock
+    def search_missing_revision_ids(self, other, revision_id=None, find_ghosts=True):
+        """Return the revision ids that other has that this does not.
+        
+        These are returned in topological order.
+
+        revision_id: only return revision ids included by revision_id.
+        """
+        return InterRepository.get(other, self).search_missing_revision_ids(
+            revision_id, find_ghosts)
+
+    @deprecated_method(symbol_versioning.one_two)
+    @needs_read_lock
     def missing_revision_ids(self, other, revision_id=None, find_ghosts=True):
         """Return the revision ids that other has that this does not.
         
@@ -859,8 +871,14 @@
 
         revision_id: only return revision ids included by revision_id.
         """
-        return InterRepository.get(other, self).missing_revision_ids(
-            revision_id, find_ghosts)
+        keys =  self.search_missing_revision_ids(
+            other, revision_id, find_ghosts).get_keys()
+        other.lock_read()
+        try:
+            parents = other.get_graph().get_parent_map(keys)
+        finally:
+            other.unlock()
+        return tsort.topo_sort(parents)
 
     @staticmethod
     def open(base):
@@ -2337,12 +2355,13 @@
             # we don't care about other ghosts as we can't fetch them and
             # haven't been asked to.
             next_revs = set(next_revs)
-            next_revs.difference_update(null_set)
-            have_revs = self.target.has_revisions(next_revs)
+            # we always have NULL_REVISION present.
+            have_revs = self.target.has_revisions(next_revs).union(null_set)
             missing_revs.update(next_revs - have_revs)
             searcher.stop_searching_any(have_revs)
-        return missing_revs
+        return searcher.get_result()
    
+    @deprecated_method(symbol_versioning.one_two)
     @needs_read_lock
     def missing_revision_ids(self, revision_id=None, find_ghosts=True):
         """Return the revision ids that source has that target does not.
@@ -2354,6 +2373,19 @@
         :param find_ghosts: If True find missing revisions in deep history
             rather than just finding the surface difference.
         """
+        return list(self.search_missing_revision_ids(
+            revision_id, find_ghosts).get_keys())
+
+    @needs_read_lock
+    def search_missing_revision_ids(self, revision_id=None, find_ghosts=True):
+        """Return the revision ids that source has that target does not.
+        
+        :param revision_id: only return revision ids included by this
+                            revision_id.
+        :param find_ghosts: If True find missing revisions in deep history
+            rather than just finding the surface difference.
+        :return: A bzrlib.graph.SearchResult.
+        """
         # stop searching at found target revisions.
         if not find_ghosts and revision_id is not None:
             return self._walk_to_common_revisions([revision_id])
@@ -2366,10 +2398,20 @@
         else:
             source_ids = self.source.all_revision_ids()
         result_set = set(source_ids).difference(target_ids)
-        # this may look like a no-op: its not. It preserves the ordering
-        # other_ids had while only returning the members from other_ids
-        # that we've decided we need.
-        return [rev_id for rev_id in source_ids if rev_id in result_set]
+        return self._set_to_search_result(result_set, self.source)
+
+    def _set_to_search_result(self, result_set, repository):
+        """Convert a set of revision ids to a graph SearchResult."""
+        result_parents = set()
+        for parents in repository.get_graph().get_parent_map(
+            result_set).itervalues():
+            result_parents.update(parents)
+        included_keys = result_set.intersection(result_parents)
+        start_keys = result_set.difference(included_keys)
+        exclude_keys = result_parents.difference(result_set)
+        result = graph.SearchResult(start_keys, exclude_keys,
+            len(result_set), result_set)
+        return result
 
     @staticmethod
     def _same_model(source, target):
@@ -2516,7 +2558,7 @@
         return f.count_copied, f.failed_revisions
 
     @needs_read_lock
-    def missing_revision_ids(self, revision_id=None, find_ghosts=True):
+    def search_missing_revision_ids(self, revision_id=None, find_ghosts=True):
         """See InterRepository.missing_revision_ids()."""
         # we want all revisions to satisfy revision_id in source.
         # but we don't want to stat every file here and there.
@@ -2542,19 +2584,21 @@
         # we do not have a revision as that would be pointless.
         target_ids = set(self.target._all_possible_ids())
         possibly_present_revisions = target_ids.intersection(source_ids_set)
-        actually_present_revisions = set(self.target._eliminate_revisions_not_present(possibly_present_revisions))
+        actually_present_revisions = set(
+            self.target._eliminate_revisions_not_present(possibly_present_revisions))
         required_revisions = source_ids_set.difference(actually_present_revisions)
-        required_topo_revisions = [rev_id for rev_id in source_ids if rev_id in required_revisions]
         if revision_id is not None:
             # we used get_ancestry to determine source_ids then we are assured all
             # revisions referenced are present as they are installed in topological order.
             # and the tip revision was validated by get_ancestry.
-            return required_topo_revisions
+            result_set = required_revisions
         else:
             # if we just grabbed the possibly available ids, then 
             # we only have an estimate of whats available and need to validate
             # that against the revision records.
-            return self.source._eliminate_revisions_not_present(required_topo_revisions)
+            result_set = set(
+                self.source._eliminate_revisions_not_present(required_revisions))
+        return self._set_to_search_result(result_set, self.source)
 
 
 class InterKnitRepo(InterSameDataRepository):
@@ -2594,7 +2638,7 @@
         return f.count_copied, f.failed_revisions
 
     @needs_read_lock
-    def missing_revision_ids(self, revision_id=None, find_ghosts=True):
+    def search_missing_revision_ids(self, revision_id=None, find_ghosts=True):
         """See InterRepository.missing_revision_ids()."""
         if revision_id is not None:
             source_ids = self.source.get_ancestry(revision_id)
@@ -2609,19 +2653,21 @@
         # we do not have a revision as that would be pointless.
         target_ids = set(self.target.all_revision_ids())
         possibly_present_revisions = target_ids.intersection(source_ids_set)
-        actually_present_revisions = set(self.target._eliminate_revisions_not_present(possibly_present_revisions))
+        actually_present_revisions = set(
+            self.target._eliminate_revisions_not_present(possibly_present_revisions))
         required_revisions = source_ids_set.difference(actually_present_revisions)
-        required_topo_revisions = [rev_id for rev_id in source_ids if rev_id in required_revisions]
         if revision_id is not None:
             # we used get_ancestry to determine source_ids then we are assured all
             # revisions referenced are present as they are installed in topological order.
             # and the tip revision was validated by get_ancestry.
-            return required_topo_revisions
+            result_set = required_revisions
         else:
             # if we just grabbed the possibly available ids, then 
             # we only have an estimate of whats available and need to validate
             # that against the revision records.
-            return self.source._eliminate_revisions_not_present(required_topo_revisions)
+            result_set = set(
+                self.source._eliminate_revisions_not_present(required_revisions))
+        return self._set_to_search_result(result_set, self.source)
 
 
 class InterPackRepo(InterSameDataRepository):
@@ -2674,8 +2720,8 @@
             return (0, [])
         else:
             try:
-                revision_ids = self.missing_revision_ids(revision_id,
-                    find_ghosts=find_ghosts)
+                revision_ids = self.search_missing_revision_ids(revision_id,
+                    find_ghosts=find_ghosts).get_keys()
             except errors.NoSuchRevision:
                 raise errors.InstallFailed([revision_id])
         packs = self.source._pack_collection.all_packs()
@@ -2692,7 +2738,7 @@
             return (0, [])
 
     @needs_read_lock
-    def missing_revision_ids(self, revision_id=None, find_ghosts=True):
+    def search_missing_revision_ids(self, revision_id=None, find_ghosts=True):
         """See InterRepository.missing_revision_ids().
         
         :param find_ghosts: Find ghosts throughout the ancestry of
@@ -2711,7 +2757,8 @@
         # have in target, but don't try to check for existence where we know
         # we do not have a revision as that would be pointless.
         target_ids = set(self.target.all_revision_ids())
-        return [r for r in source_ids if (r not in target_ids)]
+        result_set = set(source_ids).difference(target_ids)
+        return self._set_to_search_result(result_set, self.source)
 
 
 class InterModel1and2(InterRepository):
@@ -2817,7 +2864,9 @@
     def fetch(self, revision_id=None, pb=None, find_ghosts=False):
         """See InterRepository.fetch()."""
         revision_ids = self.target.missing_revision_ids(self.source,
-            revision_id, find_ghosts=find_ghosts)
+            revision_id, find_ghosts=find_ghosts).get_keys()
+        revision_ids = tsort.topo_sort(
+            self.get_graph().get_parent_map(revision_ids))
         def revisions_iterator():
             for current_revision_id in revision_ids:
                 revision = self.source.get_revision(current_revision_id)

=== modified file 'bzrlib/symbol_versioning.py'
--- a/bzrlib/symbol_versioning.py	2007-12-18 15:22:47 +0000
+++ b/bzrlib/symbol_versioning.py	2008-01-17 03:14:20 +0000
@@ -43,6 +43,7 @@
            'zero_ninetythree',
            'one_zero',
            'one_one',
+           'one_two',
            ]
 
 from warnings import warn
@@ -67,7 +68,7 @@
 one_zero = "%s was deprecated in version 1.0."
 zero_ninetythree = one_zero # Maintained for backwards compatibility
 one_one = "%s was deprecated in version 1.1."
-
+one_two = "%s was deprecated in version 1.2."
 
 def set_warning_method(method):
     """Set the warning method to be used by this module.

=== modified file 'bzrlib/tests/interrepository_implementations/test_interrepository.py'
--- a/bzrlib/tests/interrepository_implementations/test_interrepository.py	2008-01-09 00:51:01 +0000
+++ b/bzrlib/tests/interrepository_implementations/test_interrepository.py	2008-01-17 03:14:20 +0000
@@ -32,6 +32,7 @@
 import bzrlib.repofmt.weaverepo as weaverepo
 import bzrlib.repository as repository
 from bzrlib.revision import NULL_REVISION, Revision
+from bzrlib.symbol_versioning import one_two
 from bzrlib.tests import (
     TestCase,
     TestCaseWithTransport,
@@ -287,7 +288,20 @@
         tree_a.branch.repository.commit_write_group()
         tree_a.branch.repository.unlock()
 
-    def test_missing_revision_ids(self):
+    def test_missing_revision_ids_is_deprecated(self):
+        repo_b = self.make_to_repository('rev1_only')
+        repo_a = self.bzrdir.open_repository()
+        repo_b.fetch(repo_a, 'rev1')
+        # check the test will be valid
+        self.assertFalse(repo_b.has_revision('rev2'))
+        self.assertEqual(['rev2'],
+            self.applyDeprecated(one_two, repo_b.missing_revision_ids, repo_a))
+        inter = repository.InterRepository.get(repo_a, repo_b)
+        self.assertEqual(['rev2'],
+            self.applyDeprecated(one_two, inter.missing_revision_ids, None,
+                True))
+
+    def test_search_missing_revision_ids(self):
         # revision ids in repository A but not B are returned, fake ones
         # are stripped. (fake meaning no revision object, but an inventory 
         # as some formats keyed off inventory data in the past.)
@@ -297,10 +311,11 @@
         repo_b.fetch(repo_a, 'rev1')
         # check the test will be valid
         self.assertFalse(repo_b.has_revision('rev2'))
-        self.assertEqual(['rev2'],
-                         repo_b.missing_revision_ids(repo_a))
+        result = repo_b.search_missing_revision_ids(repo_a)
+        self.assertEqual(set(['rev2']), result.get_keys())
+        self.assertEqual((set(['rev2']), set(['rev1']), 1), result.get_recipe())
 
-    def test_missing_revision_ids_absent_requested_raises(self):
+    def test_search_missing_revision_ids_absent_requested_raises(self):
         # Asking for missing revisions with a tip that is itself absent in the
         # source raises NoSuchRevision.
         repo_b = self.make_to_repository('target')
@@ -309,19 +324,21 @@
         self.assertFalse(repo_a.has_revision('pizza'))
         self.assertFalse(repo_b.has_revision('pizza'))
         # Asking specifically for an absent revision errors.
-        self.assertRaises(NoSuchRevision, repo_b.missing_revision_ids, repo_a,
+        self.assertRaises(NoSuchRevision, repo_b.search_missing_revision_ids, repo_a,
             revision_id='pizza', find_ghosts=True)
-        self.assertRaises(NoSuchRevision, repo_b.missing_revision_ids, repo_a,
+        self.assertRaises(NoSuchRevision, repo_b.search_missing_revision_ids, repo_a,
             revision_id='pizza', find_ghosts=False)
 
-    def test_missing_revision_ids_revision_limited(self):
+    def test_search_missing_revision_ids_revision_limited(self):
         # revision ids in repository A that are not referenced by the
         # requested revision are not returned.
         # make a repository to compare against that is empty
         repo_b = self.make_to_repository('empty')
         repo_a = self.bzrdir.open_repository()
-        self.assertEqual(['rev1'],
-                         repo_b.missing_revision_ids(repo_a, revision_id='rev1'))
+        result = repo_b.search_missing_revision_ids(repo_a, revision_id='rev1')
+        self.assertEqual(set(['rev1']), result.get_keys())
+        self.assertEqual((set(['rev1']), set([NULL_REVISION]), 1),
+            result.get_recipe())
         
     def test_fetch_fetches_signatures_too(self):
         from_repo = self.bzrdir.open_repository()



More information about the bazaar-commits mailing list