Rev 4043: (robertc) Fix unnecessary get_parent_map calls after insert_stream in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Wed Feb 25 00:04:08 GMT 2009


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 4043
revision-id: pqm at pqm.ubuntu.com-20090225000405-09p33ue22l4h19yk
parent: pqm at pqm.ubuntu.com-20090224221910-i352mbfn0sa3bq4z
parent: robertc at robertcollins.net-20090224231953-rkp47hmdg2c84ai4
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Wed 2009-02-25 00:04:05 +0000
message:
  (robertc) Fix unnecessary get_parent_map calls after insert_stream
  	during push. (Andrew Bennetts)
modified:
  bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
  bzrlib/smart/repository.py     repository.py-20061128022038-vr5wy5bubyb8xttk-1
  bzrlib/tests/branch_implementations/test_push.py test_push.py-20070130153159-fhfap8uoifevg30j-1
    ------------------------------------------------------------
    revno: 4035.2.3
    revision-id: robertc at robertcollins.net-20090224231953-rkp47hmdg2c84ai4
    parent: robertc at robertcollins.net-20090224223938-3msunxpyk4cki95d
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: integration
    timestamp: Wed 2009-02-25 10:19:53 +1100
    message:
      Fix trailing whitespace.
    modified:
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
    ------------------------------------------------------------
    revno: 4035.2.2
    revision-id: robertc at robertcollins.net-20090224223938-3msunxpyk4cki95d
    parent: andrew.bennetts at canonical.com-20090224060251-25g4k13lh1sekza6
    parent: pqm at pqm.ubuntu.com-20090224203358-pxxf7n5ybvzm3mnh
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: integration
    timestamp: Wed 2009-02-25 09:39:38 +1100
    message:
      Minor tweaks to fix failing tests.
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/bzrdir.py               bzrdir.py-20060131065624-156dfea39c4387cb
      bzrlib/info.py                 info.py-20050323235939-6bbfe7d9700b0b9b
      bzrlib/push.py                 push.py-20080606021927-5fe39050e8xne9un-1
      bzrlib/registry.py             lazy_factory.py-20060809213415-2gfvqadtvdn0phtg-1
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
      bzrlib/smart/bzrdir.py         bzrdir.py-20061122024551-ol0l0o0oofsu9b3t-1
      bzrlib/smart/request.py        request.py-20061108095550-gunadhxmzkdjfeek-1
      bzrlib/tests/blackbox/test_info.py test_info.py-20060215045507-bbdd2d34efab9e0a
      bzrlib/tests/blackbox/test_push.py test_push.py-20060329002750-929af230d5d22663
      bzrlib/tests/blackbox/test_upgrade.py test_upgrade.py-20060120060132-b41e5ed2f886ad28
      bzrlib/tests/branch_implementations/test_branch.py testbranch.py-20050711070244-121d632bc37d7253
      bzrlib/tests/branch_implementations/test_hooks.py test_hooks.py-20070129154855-blhpwxmvjs07waei-1
      bzrlib/tests/branch_implementations/test_push.py test_push.py-20070130153159-fhfap8uoifevg30j-1
      bzrlib/tests/branch_implementations/test_sprout.py test_sprout.py-20070521151739-b8t8p7axw1h966ws-1
      bzrlib/tests/per_repository/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
      bzrlib/tests/test_errors.py    test_errors.py-20060210110251-41aba2deddf936a8
      bzrlib/tests/test_read_bundle.py test_read_bundle.py-20060615211421-ud8cwr1ulgd914zf-1
      bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
    ------------------------------------------------------------
    revno: 4035.2.1
    revision-id: andrew.bennetts at canonical.com-20090224060251-25g4k13lh1sekza6
    parent: pqm at pqm.ubuntu.com-20090223205523-xp0lqm5iz1df5o0x
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: bug-331823
    timestamp: Tue 2009-02-24 17:02:51 +1100
    message:
      Fix unnecessary get_parent_map calls after insert_stream during push.
    modified:
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/smart/repository.py     repository.py-20061128022038-vr5wy5bubyb8xttk-1
      bzrlib/tests/branch_implementations/test_push.py test_push.py-20070130153159-fhfap8uoifevg30j-1
=== modified file 'bzrlib/remote.py'
--- a/bzrlib/remote.py	2009-02-24 08:09:17 +0000
+++ b/bzrlib/remote.py	2009-02-24 23:19:53 +0000
@@ -865,10 +865,18 @@
         #
         # We need to accumulate additional repositories here, to pass them in
         # on various RPC's.
+        #
         self._fallback_repositories.append(repository)
-        # They are also seen by the fallback repository.  If it doesn't exist
-        # yet they'll be added then.  This implicitly copies them.
-        self._ensure_real()
+        # If self._real_repository was parameterised already (e.g. because a
+        # _real_branch had its get_stacked_on_url method called), then the
+        # repository to be added may already be in the _real_repositories list.
+        if self._real_repository is not None:
+            if repository not in self._real_repository._fallback_repositories:
+                self._real_repository.add_fallback_repository(repository)
+        else:
+            # They are also seen by the fallback repository.  If it doesn't
+            # exist yet they'll be added then.  This implicitly copies them.
+            self._ensure_real()
 
     def add_inventory(self, revid, inv, parents):
         self._ensure_real()
@@ -1639,10 +1647,14 @@
         fallback_url = urlutils.join(self.base, fallback_url)
         transports = [self.bzrdir.root_transport]
         if self._real_branch is not None:
+            # The real repository is setup already:
             transports.append(self._real_branch._transport)
-        stacked_on = branch.Branch.open(fallback_url,
-                                        possible_transports=transports)
-        self.repository.add_fallback_repository(stacked_on.repository)
+            self.repository.add_fallback_repository(
+                self.repository._real_repository._fallback_repositories[0])
+        else:
+            stacked_on = branch.Branch.open(fallback_url,
+                                            possible_transports=transports)
+            self.repository.add_fallback_repository(stacked_on.repository)
 
     def _get_real_transport(self):
         # if we try vfs access, return the real branch's vfs transport
@@ -2047,45 +2059,6 @@
         self._ensure_real()
         return self._real_branch.set_push_location(location)
 
-    @needs_write_lock
-    def update_revisions(self, other, stop_revision=None, overwrite=False,
-                         graph=None):
-        """See Branch.update_revisions."""
-        other.lock_read()
-        try:
-            if stop_revision is None:
-                stop_revision = other.last_revision()
-                if revision.is_null(stop_revision):
-                    # if there are no commits, we're done.
-                    return
-            self.fetch(other, stop_revision)
-
-            if overwrite:
-                # Just unconditionally set the new revision.  We don't care if
-                # the branches have diverged.
-                self._set_last_revision(stop_revision)
-            else:
-                medium = self._client._medium
-                if not medium._is_remote_before((1, 6)):
-                    try:
-                        self._set_last_revision_descendant(stop_revision, other)
-                        return
-                    except errors.UnknownSmartMethod:
-                        medium._remember_remote_is_before((1, 6))
-                # Fallback for pre-1.6 servers: check for divergence
-                # client-side, then do _set_last_revision.
-                last_rev = revision.ensure_null(self.last_revision())
-                if graph is None:
-                    graph = self.repository.get_graph()
-                if self._check_if_descendant_or_diverged(
-                        stop_revision, last_rev, graph, other):
-                    # stop_revision is a descendant of last_rev, but we aren't
-                    # overwriting, so we're done.
-                    return
-                self._set_last_revision(stop_revision)
-        finally:
-            other.unlock()
-
 
 def _extract_tar(tar, to_dir):
     """Extract all the contents of a tarfile object.

=== modified file 'bzrlib/smart/repository.py'
--- a/bzrlib/smart/repository.py	2009-02-23 15:29:35 +0000
+++ b/bzrlib/smart/repository.py	2009-02-24 06:02:51 +0000
@@ -113,6 +113,8 @@
 class SmartServerRepositoryGetParentMap(SmartServerRepositoryRequest):
     """Bzr 1.2+ - get parent data for revisions during a graph search."""
 
+    no_extra_results = False
+
     def do_repository_request(self, repository, *revision_ids):
         """Get parent details for some revisions.
 
@@ -180,7 +182,8 @@
             # 64K (compressed) or so. We do one level of depth at a time to
             # stay in sync with the client. The 250000 magic number is
             # estimated compression ratio taken from bzr.dev itself.
-            if first_loop_done and size_so_far > 250000:
+            if self.no_extra_results or (
+                first_loop_done and size_so_far > 250000):
                 next_revs = set()
                 break
             # don't query things we've already queried

=== modified file 'bzrlib/tests/branch_implementations/test_push.py'
--- a/bzrlib/tests/branch_implementations/test_push.py	2009-01-17 01:30:58 +0000
+++ b/bzrlib/tests/branch_implementations/test_push.py	2009-02-24 22:39:38 +0000
@@ -26,6 +26,7 @@
     debug,
     errors,
     push,
+    repository,
     tests,
     )
 from bzrlib.branch import Branch
@@ -33,6 +34,7 @@
 from bzrlib.memorytree import MemoryTree
 from bzrlib.revision import NULL_REVISION
 from bzrlib.smart import client, server
+from bzrlib.smart.repository import SmartServerRepositoryGetParentMap
 from bzrlib.tests.branch_implementations.test_branch import TestCaseWithBranch
 from bzrlib.transport import get_transport
 from bzrlib.transport.local import LocalURLServer
@@ -224,6 +226,68 @@
         trunk.push(remote_branch)
         remote_branch.check()
 
+    def test_no_get_parent_map_after_insert_stream(self):
+        # Effort test for bug 331823
+        self.setup_smart_server_with_call_log()
+        # Make a local branch with four revisions.  Four revisions because:
+        # one to push, one there for _walk_to_common_revisions to find, one we
+        # don't want to access, one for luck :)
+        if isinstance(self.branch_format, branch.BranchReferenceFormat):
+            # This test could in principle apply to BranchReferenceFormat, but
+            # make_branch_builder doesn't support it.
+            raise tests.TestSkipped(
+                "BranchBuilder can't make reference branches.")
+        try:
+            builder = self.make_branch_builder('local')
+        except (errors.TransportNotPossible, errors.UninitializableFormat):
+            raise tests.TestNotApplicable('format not directly constructable')
+        builder.start_series()
+        builder.build_snapshot('first', None, [
+            ('add', ('', 'root-id', 'directory', ''))])
+        builder.build_snapshot('second', ['first'], [])
+        builder.build_snapshot('third', ['second'], [])
+        builder.build_snapshot('fourth', ['third'], [])
+        builder.finish_series()
+        local = builder.get_branch()
+        local = branch.Branch.open(self.get_vfs_only_url('local'))
+        # Initial push of three revisions
+        remote_bzrdir = local.bzrdir.sprout(
+            self.get_url('remote'), revision_id='third')
+        remote = remote_bzrdir.open_branch()
+        # Push fourth revision
+        self.reset_smart_call_log()
+        self.disableOptimisticGetParentMap()
+        self.assertFalse(local.is_locked())
+        local.push(remote)
+        hpss_call_names = [item[0].method for item in self.hpss_calls]
+        self.assertTrue('Repository.insert_stream' in hpss_call_names)
+        insert_stream_idx = hpss_call_names.index('Repository.insert_stream')
+        calls_after_insert_stream = hpss_call_names[insert_stream_idx:]
+        # After inserting the stream the client has no reason to query the
+        # remote graph any further.
+        self.assertEqual(
+            ['Repository.insert_stream', 'Repository.insert_stream', 'get',
+             'delete', 'Branch.set_last_revision_info', 'Branch.unlock'],
+            calls_after_insert_stream)
+
+    def disableOptimisticGetParentMap(self):
+        # Tweak some class variables to stop remote get_parent_map calls asking
+        # for or receiving more data than the caller asked for.
+        old_flag = SmartServerRepositoryGetParentMap.no_extra_results
+        inter_classes = [repository.InterOtherToRemote,
+            repository.InterPackToRemotePack]
+        old_batch_sizes = []
+        for inter_class in inter_classes:
+            old_batch_sizes.append(
+                inter_class._walk_to_common_revisions_batch_size)
+            inter_class._walk_to_common_revisions_batch_size = 1
+        SmartServerRepositoryGetParentMap.no_extra_results = True
+        def reset_values():
+            SmartServerRepositoryGetParentMap.no_extra_results = old_flag
+            for inter_class, size in zip(inter_classes, old_batch_sizes):
+                inter_class._walk_to_common_revisions_batch_size = size
+        self.addCleanup(reset_values)
+
 
 class TestPushHook(TestCaseWithBranch):
 




More information about the bazaar-commits mailing list