Rev 3952: Branch methods for fast revno <=> revision_id mapping (Ian Clatworthy) in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Thu Jan 22 15:16:32 GMT 2009


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

------------------------------------------------------------
revno: 3952
revision-id: pqm at pqm.ubuntu.com-20090122151628-iw1va4nlci8v2afw
parent: pqm at pqm.ubuntu.com-20090122115937-y54v6rziznwn10yu
parent: ian.clatworthy at canonical.com-20090122143647-55dpxsjay6c8izj2
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Thu 2009-01-22 15:16:28 +0000
message:
  Branch methods for fast revno <=> revision_id mapping (Ian Clatworthy)
added:
  bzrlib/tests/branch_implementations/test_dotted_revno_to_revision_id.py test_dotted_revno_to-20090121014844-6x7d9jtri5sspg1o-1
  bzrlib/tests/branch_implementations/test_revision_id_to_dotted_revno.py test_revision_id_to_-20090122052032-g3czslif6sdqfkh3-1
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
  bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
  bzrlib/revisionspec.py         revisionspec.py-20050907152633-17567659fd5c0ddb
  bzrlib/tests/branch_implementations/__init__.py __init__.py-20060123013057-b12a52c3f361daf4
    ------------------------------------------------------------
    revno: 3951.1.2
    revision-id: ian.clatworthy at canonical.com-20090122143647-55dpxsjay6c8izj2
    parent: ian.clatworthy at canonical.com-20090122140219-ho1fs4kx9k0tzskz
    parent: ian.clatworthy at canonical.com-20090122142434-4i60r8rwujkom5t2
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: ianc-integration
    timestamp: Fri 2009-01-23 00:36:47 +1000
    message:
      fix accidental needs_read_lock removal
    modified:
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
        ------------------------------------------------------------
        revno: 3949.2.7
        revision-id: ian.clatworthy at canonical.com-20090122142434-4i60r8rwujkom5t2
        parent: ian.clatworthy at canonical.com-20090122135818-twftjodatp3cm7xm
        committer: Ian Clatworthy <ian.clatworthy at canonical.com>
        branch nick: bzr.dotted-revno-to-revision-id
        timestamp: Fri 2009-01-23 00:24:34 +1000
        message:
          fix accidental needs_read_lock removal
        modified:
          bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
    ------------------------------------------------------------
    revno: 3951.1.1
    revision-id: ian.clatworthy at canonical.com-20090122140219-ho1fs4kx9k0tzskz
    parent: pqm at pqm.ubuntu.com-20090122115937-y54v6rziznwn10yu
    parent: ian.clatworthy at canonical.com-20090122135818-twftjodatp3cm7xm
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: ianc-integration
    timestamp: Fri 2009-01-23 00:02:19 +1000
    message:
      Branch methods for fast revno <=> revision_id mapping (Ian Clatworthy)
    added:
      bzrlib/tests/branch_implementations/test_dotted_revno_to_revision_id.py test_dotted_revno_to-20090121014844-6x7d9jtri5sspg1o-1
      bzrlib/tests/branch_implementations/test_revision_id_to_dotted_revno.py test_revision_id_to_-20090122052032-g3czslif6sdqfkh3-1
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/revisionspec.py         revisionspec.py-20050907152633-17567659fd5c0ddb
      bzrlib/tests/branch_implementations/__init__.py __init__.py-20060123013057-b12a52c3f361daf4
    ------------------------------------------------------------
    revno: 3949.2.6
    revision-id: ian.clatworthy at canonical.com-20090122135818-twftjodatp3cm7xm
    parent: ian.clatworthy at canonical.com-20090122053359-0ozol6xxjiyv2p4q
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: bzr.dotted-revno-to-revision-id
    timestamp: Thu 2009-01-22 23:58:18 +1000
    message:
      review feedback from jam
    modified:
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/revisionspec.py         revisionspec.py-20050907152633-17567659fd5c0ddb
      bzrlib/tests/branch_implementations/test_dotted_revno_to_revision_id.py test_dotted_revno_to-20090121014844-6x7d9jtri5sspg1o-1
    ------------------------------------------------------------
    revno: 3949.2.5
    revision-id: ian.clatworthy at canonical.com-20090122053359-0ozol6xxjiyv2p4q
    parent: ian.clatworthy at canonical.com-20090122051710-gqka9rzkxc93p20m
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: bzr.dotted-revno-to-revision-id
    timestamp: Thu 2009-01-22 15:33:59 +1000
    message:
      add missing test module
    added:
      bzrlib/tests/branch_implementations/test_revision_id_to_dotted_revno.py test_revision_id_to_-20090122052032-g3czslif6sdqfkh3-1
    ------------------------------------------------------------
    revno: 3949.2.4
    revision-id: ian.clatworthy at canonical.com-20090122051710-gqka9rzkxc93p20m
    parent: ian.clatworthy at canonical.com-20090122044330-mhe4tkrgbzwuepju
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: bzr.dotted-revno-to-revision-id
    timestamp: Thu 2009-01-22 15:17:10 +1000
    message:
      add top level revno cache
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/revisionspec.py         revisionspec.py-20050907152633-17567659fd5c0ddb
      bzrlib/tests/branch_implementations/test_dotted_revno_to_revision_id.py test_dotted_revno_to-20090121014844-6x7d9jtri5sspg1o-1
    ------------------------------------------------------------
    revno: 3949.2.3
    revision-id: ian.clatworthy at canonical.com-20090122044330-mhe4tkrgbzwuepju
    parent: ian.clatworthy at canonical.com-20090121015117-xhiiodxp5meqen0w
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: bzr.dotted-revno-to-revision-id
    timestamp: Thu 2009-01-22 14:43:30 +1000
    message:
      add Branch.revision_id_to_dotted_revno()
    modified:
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/tests/branch_implementations/__init__.py __init__.py-20060123013057-b12a52c3f361daf4
    ------------------------------------------------------------
    revno: 3949.2.2
    revision-id: ian.clatworthy at canonical.com-20090121015117-xhiiodxp5meqen0w
    parent: ian.clatworthy at canonical.com-20090121014010-a40vzg1x44d2d6oe
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: bzr.dotted-revno-to-revision-id
    timestamp: Wed 2009-01-21 11:51:17 +1000
    message:
      add interface test and NEWS item
    added:
      bzrlib/tests/branch_implementations/test_dotted_revno_to_revision_id.py test_dotted_revno_to-20090121014844-6x7d9jtri5sspg1o-1
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/tests/branch_implementations/__init__.py __init__.py-20060123013057-b12a52c3f361daf4
    ------------------------------------------------------------
    revno: 3949.2.1
    revision-id: ian.clatworthy at canonical.com-20090121014010-a40vzg1x44d2d6oe
    parent: pqm at pqm.ubuntu.com-20090120210300-641tutf1rkdn8a3n
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: bzr.dotted-revno-to-revision-id
    timestamp: Wed 2009-01-21 11:40:10 +1000
    message:
      Branch.dotted_revno_to_revision_id API
    modified:
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/revisionspec.py         revisionspec.py-20050907152633-17567659fd5c0ddb
=== modified file 'NEWS'
--- a/NEWS	2009-01-22 09:43:03 +0000
+++ b/NEWS	2009-01-22 14:02:19 +0000
@@ -62,6 +62,11 @@
       compile buffers, are such an example).
       (Vincent Ladeuil)
 
+    * New ``Branch.dotted_revno_to_revision_id()`` and
+      ``Branch.revision_id_to_dotted_revno()`` APIs that pick the most
+      efficient way of doing the mapping.
+      (Ian Clatworthy)
+
     * ``TreeDelta.show()`` now accepts a ``filter`` parameter allowing log
       formatters to retrict the output.
       (Vincent Ladeuil)

=== modified file 'bzrlib/branch.py'
--- a/bzrlib/branch.py	2009-01-08 19:15:20 +0000
+++ b/bzrlib/branch.py	2009-01-22 14:24:34 +0000
@@ -89,6 +89,7 @@
         self.tags = self._make_tags()
         self._revision_history_cache = None
         self._revision_id_to_revno_cache = None
+        self._partial_revision_id_to_revno_cache = {}
         self._last_revision_info_cache = None
         self._open_hook()
         hooks = Branch.hooks['open']
@@ -189,6 +190,70 @@
         raise NotImplementedError(self.get_physical_lock_status)
 
     @needs_read_lock
+    def dotted_revno_to_revision_id(self, revno, _cache_reverse=False):
+        """Return the revision_id for a dotted revno.
+
+        :param revno: a tuple like (1,) or (1,1,2)
+        :param _cache_reverse: a private parameter enabling storage
+           of the reverse mapping in a top level cache. (This should
+           only be done in selective circumstances as we want to
+           avoid having the mapping cached multiple times.)
+        :return: the revision_id
+        :raises errors.NoSuchRevision: if the revno doesn't exist
+        """
+        rev_id = self._do_dotted_revno_to_revision_id(revno)
+        if _cache_reverse:
+            self._partial_revision_id_to_revno_cache[rev_id] = revno
+        return rev_id
+
+    def _do_dotted_revno_to_revision_id(self, revno):
+        """Worker function for dotted_revno_to_revision_id.
+
+        Subclasses should override this if they wish to
+        provide a more efficient implementation.
+        """
+        if len(revno) == 1:
+            return self.get_rev_id(revno[0])
+        revision_id_to_revno = self.get_revision_id_to_revno_map()
+        revision_ids = [revision_id for revision_id, this_revno
+                        in revision_id_to_revno.iteritems()
+                        if revno == this_revno]
+        if len(revision_ids) == 1:
+            return revision_ids[0]
+        else:
+            revno_str = '.'.join(map(str, revno))
+            raise errors.NoSuchRevision(self, revno_str)
+
+    @needs_read_lock
+    def revision_id_to_dotted_revno(self, revision_id):
+        """Given a revision id, return its dotted revno.
+        
+        :return: a tuple like (1,) or (400,1,3).
+        """
+        return self._do_revision_id_to_dotted_revno(revision_id)
+
+    def _do_revision_id_to_dotted_revno(self, revision_id):
+        """Worker function for revision_id_to_revno."""
+        # Try the caches if they are loaded
+        result = self._partial_revision_id_to_revno_cache.get(revision_id)
+        if result is not None:
+            return result
+        if self._revision_id_to_revno_cache:
+            result = self._revision_id_to_revno_cache.get(revision_id)
+            if result is None:
+                raise errors.NoSuchRevision(self, revision_id)
+        # Try the mainline as it's optimised
+        try:
+            revno = self.revision_id_to_revno(revision_id)
+            return (revno,)
+        except errors.NoSuchRevision:
+            # We need to load and use the full revno map after all
+            result = self.get_revision_id_to_revno_map().get(revision_id)
+            if result is None:
+                raise errors.NoSuchRevision(self, revision_id)
+        return result
+
+    @needs_read_lock
     def get_revision_id_to_revno_map(self):
         """Return the revision_id => dotted revno map.
 

=== modified file 'bzrlib/remote.py'
--- a/bzrlib/remote.py	2009-01-16 07:50:48 +0000
+++ b/bzrlib/remote.py	2009-01-22 13:58:18 +0000
@@ -1287,6 +1287,7 @@
         # will try to assign to self.tags, which is a property in this subclass.
         # And the parent's __init__ doesn't do much anyway.
         self._revision_id_to_revno_cache = None
+        self._partial_revision_id_to_revno_cache = {}
         self._revision_history_cache = None
         self._last_revision_info_cache = None
         self.bzrdir = remote_bzrdir

=== modified file 'bzrlib/revisionspec.py'
--- a/bzrlib/revisionspec.py	2008-12-09 14:04:01 +0000
+++ b/bzrlib/revisionspec.py	2009-01-22 13:58:18 +0000
@@ -352,20 +352,15 @@
             revs_or_none = None
 
         if dotted:
-            branch.lock_read()
             try:
-                revision_id_to_revno = branch.get_revision_id_to_revno_map()
-                revisions = [revision_id for revision_id, revno
-                             in revision_id_to_revno.iteritems()
-                             if revno == match_revno]
-            finally:
-                branch.unlock()
-            if len(revisions) != 1:
+                revision_id = branch.dotted_revno_to_revision_id(match_revno,
+                    _cache_reverse=True)
+            except errors.NoSuchRevision:
                 raise errors.InvalidRevisionSpec(self.user_spec, branch)
             else:
                 # there is no traditional 'revno' for dotted-decimal revnos.
                 # so for  API compatability we return None.
-                return branch, None, revisions[0]
+                return branch, None, revision_id
         else:
             last_revno, last_revision_id = branch.last_revision_info()
             if revno < 0:

=== modified file 'bzrlib/tests/branch_implementations/__init__.py'
--- a/bzrlib/tests/branch_implementations/__init__.py	2008-12-16 02:15:06 +0000
+++ b/bzrlib/tests/branch_implementations/__init__.py	2009-01-22 04:43:30 +0000
@@ -157,6 +157,7 @@
         'bzrlib.tests.branch_implementations.test_check',
         'bzrlib.tests.branch_implementations.test_create_checkout',
         'bzrlib.tests.branch_implementations.test_commit',
+        'bzrlib.tests.branch_implementations.test_dotted_revno_to_revision_id',
         'bzrlib.tests.branch_implementations.test_get_revision_id_to_revno_map',
         'bzrlib.tests.branch_implementations.test_hooks',
         'bzrlib.tests.branch_implementations.test_http',
@@ -168,6 +169,7 @@
         'bzrlib.tests.branch_implementations.test_push',
         'bzrlib.tests.branch_implementations.test_reconcile',
         'bzrlib.tests.branch_implementations.test_revision_history',
+        'bzrlib.tests.branch_implementations.test_revision_id_to_dotted_revno',
         'bzrlib.tests.branch_implementations.test_revision_id_to_revno',
         'bzrlib.tests.branch_implementations.test_sprout',
         'bzrlib.tests.branch_implementations.test_stacking',

=== added file 'bzrlib/tests/branch_implementations/test_dotted_revno_to_revision_id.py'
--- a/bzrlib/tests/branch_implementations/test_dotted_revno_to_revision_id.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/tests/branch_implementations/test_dotted_revno_to_revision_id.py	2009-01-22 13:58:18 +0000
@@ -0,0 +1,43 @@
+# Copyright (C) 2007 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+"""Tests for Branch.dotted_revno_to_revision_id()"""
+
+from bzrlib import errors
+
+from bzrlib.tests.branch_implementations import TestCaseWithBranch
+
+
+class TestDottedRevnoToRevisionId(TestCaseWithBranch):
+
+    def test_lookup_revision_id_by_dotted(self):
+        tree = self.create_tree_with_merge()
+        the_branch = tree.branch
+        self.assertEqual('null:', the_branch.dotted_revno_to_revision_id((0,)))
+        self.assertEqual('rev-1', the_branch.dotted_revno_to_revision_id((1,)))
+        self.assertEqual('rev-2', the_branch.dotted_revno_to_revision_id((2,)))
+        self.assertEqual('rev-3', the_branch.dotted_revno_to_revision_id((3,)))
+        self.assertEqual('rev-1.1.1', the_branch.dotted_revno_to_revision_id(
+            (1,1,1)))
+        self.assertRaises(errors.NoSuchRevision,
+                          the_branch.dotted_revno_to_revision_id, (1,0,2))
+        # Test reverse caching
+        self.assertEqual(None,
+            the_branch._partial_revision_id_to_revno_cache.get('rev-1'))
+        self.assertEqual('rev-1', the_branch.dotted_revno_to_revision_id((1,),
+            _cache_reverse=True))
+        self.assertEqual((1,),
+            the_branch._partial_revision_id_to_revno_cache.get('rev-1'))

=== added file 'bzrlib/tests/branch_implementations/test_revision_id_to_dotted_revno.py'
--- a/bzrlib/tests/branch_implementations/test_revision_id_to_dotted_revno.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/tests/branch_implementations/test_revision_id_to_dotted_revno.py	2009-01-22 05:33:59 +0000
@@ -0,0 +1,36 @@
+# Copyright (C) 2007 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+"""Tests for Branch.revision_id_to_dotted_revno()"""
+
+from bzrlib import errors
+
+from bzrlib.tests.branch_implementations import TestCaseWithBranch
+
+
+class TestRevisionIdToDottedRevno(TestCaseWithBranch):
+
+    def test_lookup_dotted_revno(self):
+        tree = self.create_tree_with_merge()
+        the_branch = tree.branch
+        self.assertEqual((0,), the_branch.revision_id_to_dotted_revno('null:'))
+        self.assertEqual((1,), the_branch.revision_id_to_dotted_revno('rev-1'))
+        self.assertEqual((2,), the_branch.revision_id_to_dotted_revno('rev-2'))
+        self.assertEqual((3,), the_branch.revision_id_to_dotted_revno('rev-3'))
+        self.assertEqual((1,1,1), the_branch.revision_id_to_dotted_revno(
+            'rev-1.1.1'))
+        self.assertRaises(errors.NoSuchRevision,
+                          the_branch.revision_id_to_dotted_revno, 'rev-1.0.2')




More information about the bazaar-commits mailing list