Rev 3209: (jam) Optimize 'annotate' code path in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Wed Jan 30 21:20:59 GMT 2008


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

------------------------------------------------------------
revno: 3209
revision-id:pqm at pqm.ubuntu.com-20080130212051-utcw5p2zydlq6ntb
parent: pqm at pqm.ubuntu.com-20080130194701-iykyel7v3q52qsol
parent: john at arbash-meinel.com-20080130184147-l30omu7r7cln13at
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Wed 2008-01-30 21:20:51 +0000
message:
  (jam) Optimize 'annotate' code path
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/annotate.py             annotate.py-20050922133147-7c60541d2614f022
    ------------------------------------------------------------
    revno: 3180.2.4
    revision-id:john at arbash-meinel.com-20080130184147-l30omu7r7cln13at
    parent: john at arbash-meinel.com-20080130181142-mmgn0wrdvxu38ba5
    committer: John Arbash Meinel <john at arbash-meinel.com>
    branch nick: optim_annotate
    timestamp: Wed 2008-01-30 12:41:47 -0600
    message:
      NEWS
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
    ------------------------------------------------------------
    revno: 3180.2.3
    revision-id:john at arbash-meinel.com-20080130181142-mmgn0wrdvxu38ba5
    parent: john at arbash-meinel.com-20080130181024-fu7u323c9paee4n5
    parent: pqm at pqm.ubuntu.com-20080130100306-p0uqnxt3hodnyiej
    committer: John Arbash Meinel <john at arbash-meinel.com>
    branch nick: optim_annotate
    timestamp: Wed 2008-01-30 12:11:42 -0600
    message:
      [merge] bzr.dev 3207
    removed:
      bzrlib/plugins/multiparent.py  mpregen-20070411063203-5x9z7i73add0d6f6-1
    added:
      doc/en/user-guide/revnos.txt   revnos.txt-20080111231928-pbntxea0ynh9ww1t-1
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzr                            bzr.py-20050313053754-5485f144c7006fa6
      bzrlib/__init__.py             __init__.py-20050309040759-33e65acf91bbcd5d
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/bzrdir.py               bzrdir.py-20060131065624-156dfea39c4387cb
      bzrlib/commands.py             bzr.py-20050309040720-d10f4714595cf8c3
      bzrlib/debug.py                debug.py-20061102062349-vdhrw9qdpck8cl35-1
      bzrlib/doc/api/__init__.py     __init__.py-20051224020744-7b87d590843855bc
      bzrlib/fetch.py                fetch.py-20050818234941-26fea6105696365d
      bzrlib/graph.py                graph_walker.py-20070525030359-y852guab65d4wtn0-1
      bzrlib/help_topics/__init__.py help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
      bzrlib/merge.py                merge.py-20050513021216-953b65a438527106
      bzrlib/plugin.py               plugin.py-20050622060424-829b654519533d69
      bzrlib/reconfigure.py          reconfigure.py-20070908040425-6ykgo7escxhyrg9p-1
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/repofmt/knitrepo.py     knitrepo.py-20070206081537-pyy4a00xdas0j4pf-1
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
      bzrlib/revisiontree.py         revisiontree.py-20060724012533-bg8xyryhxd0o0i0h-1
      bzrlib/smart/client.py         client.py-20061116014825-2k6ada6xgulslami-1
      bzrlib/smart/medium.py         medium.py-20061103051856-rgu2huy59fkz902q-1
      bzrlib/smart/protocol.py       protocol.py-20061108035435-ot0lstk2590yqhzr-1
      bzrlib/smart/repository.py     repository.py-20061128022038-vr5wy5bubyb8xttk-1
      bzrlib/smart/request.py        request.py-20061108095550-gunadhxmzkdjfeek-1
      bzrlib/status.py               status.py-20050505062338-431bfa63ec9b19e6
      bzrlib/symbol_versioning.py    symbol_versioning.py-20060105104851-9ecf8af605d15a80
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/tests/blackbox/test_log.py test_log.py-20060112090212-78f6ea560c868e24
      bzrlib/tests/blackbox/test_merge.py test_merge.py-20060323225809-9bc0459c19917f41
      bzrlib/tests/blackbox/test_outside_wt.py test_outside_wt.py-20060116200058-98edd33e7db8bdde
      bzrlib/tests/blackbox/test_selftest.py test_selftest.py-20060123024542-01c5f1bbcb596d78
      bzrlib/tests/interrepository_implementations/test_interrepository.py test_interrepository.py-20060220061411-1ec13fa99e5e3eee
      bzrlib/tests/repository_implementations/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
      bzrlib/tests/test_annotate.py  test_annotate.py-20061213215015-sttc9agsxomls7q0-1
      bzrlib/tests/test_diff.py      testdiff.py-20050727164403-d1a3496ebb12e339
      bzrlib/tests/test_graph.py     test_graph_walker.py-20070525030405-enq4r60hhi9xrujc-1
      bzrlib/tests/test_http.py      testhttp.py-20051018020158-b2eef6e867c514d9
      bzrlib/tests/test_log.py       testlog.py-20050728115707-1a514809d7d49309
      bzrlib/tests/test_merge.py     testmerge.py-20050905070950-c1b5aa49ff911024
      bzrlib/tests/test_merge_core.py test_merge_core.py-20050824132511-eb99b23a0eec641b
      bzrlib/tests/test_osutils.py   test_osutils.py-20051201224856-e48ee24c12182989
      bzrlib/tests/test_plugins.py   plugins.py-20050622075746-32002b55e5e943e9
      bzrlib/tests/test_reconfigure.py test_reconfigure.py-20070908040425-6ykgo7escxhyrg9p-2
      bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
      bzrlib/tests/test_repository.py test_repository.py-20060131075918-65c555b881612f4d
      bzrlib/tests/test_selftest.py  test_selftest.py-20051202044319-c110a115d8c0456a
      bzrlib/tests/test_smart.py     test_smart.py-20061122024551-ol0l0o0oofsu9b3t-2
      bzrlib/tests/test_smart_transport.py test_ssh_transport.py-20060608202016-c25gvf1ob7ypbus6-2
      bzrlib/tests/test_trace.py     testtrace.py-20051110225523-a21117fc7a07eeff
      bzrlib/tests/test_transform.py test_transaction.py-20060105172520-b3ffb3946550e6c4
      bzrlib/tests/test_tsort.py     testtsort.py-20051025073946-27da871c394d5be4
      bzrlib/trace.py                trace.py-20050309040759-c8ed824bdcd4748a
      bzrlib/transform.py            transform.py-20060105172343-dd99e54394d91687
      bzrlib/transport/remote.py     ssh.py-20060608202016-c25gvf1ob7ypbus6-1
      bzrlib/tsort.py                tsort.py-20051025073946-7808f6aaf7d07208
      doc/developers/HACKING.txt     HACKING-20050805200004-2a5dc975d870f78c
      doc/en/user-guide/core_concepts.txt core_concepts.txt-20071114035000-q36a9h57ps06uvnl-2
      doc/en/user-guide/index.txt    index.txt-20060622101119-tgwtdci8z769bjb9-2
    ------------------------------------------------------------
    revno: 3180.2.2
    revision-id:john at arbash-meinel.com-20080130181024-fu7u323c9paee4n5
    parent: john at arbash-meinel.com-20080124225422-atibw1m93vdmtjw9
    committer: John Arbash Meinel <john at arbash-meinel.com>
    branch nick: optim_annotate
    timestamp: Wed 2008-01-30 12:10:24 -0600
    message:
      Fix typo, (thanks Ian)
    modified:
      bzrlib/annotate.py             annotate.py-20050922133147-7c60541d2614f022
    ------------------------------------------------------------
    revno: 3180.2.1
    revision-id:john at arbash-meinel.com-20080124225422-atibw1m93vdmtjw9
    parent: pqm at pqm.ubuntu.com-20080115003405-jfuumkpctmvl2e4r
    committer: John Arbash Meinel <john at arbash-meinel.com>
    branch nick: optim_annotate
    timestamp: Thu 2008-01-24 16:54:22 -0600
    message:
      Change reannotate to special case the 2-parent case.
      This allows a few cheap optimizations which saves a lot of time for annotate.
    modified:
      bzrlib/annotate.py             annotate.py-20050922133147-7c60541d2614f022
=== modified file 'NEWS'
--- a/NEWS	2008-01-30 19:47:01 +0000
+++ b/NEWS	2008-01-30 21:20:51 +0000
@@ -43,6 +43,10 @@
     * The ``--coverage`` option is now global, rather specific to ``bzr
       selftest``.  (Andrew Bennetts)
 
+    * Tweak the ``reannotate`` code path to optimize the 2-parent case.
+      Speeds up ``bzr annotate`` with a pack repository by approx 3:2.
+      (John Arbash Meinel)
+
   BUGFIXES:
 
     * Calculate remote path relative to the shared medium in _SmartClient.  This

=== modified file 'bzrlib/annotate.py'
--- a/bzrlib/annotate.py	2007-11-21 21:57:11 +0000
+++ b/bzrlib/annotate.py	2008-01-30 18:10:24 +0000
@@ -168,25 +168,48 @@
         the SequenceMatcher.get_matching_blocks format.
     """
     if len(parents_lines) == 0:
-        for line in new_lines:
-            yield new_revision_id, line
+        lines = [(new_revision_id, line) for line in new_lines]
     elif len(parents_lines) == 1:
-        for data in _reannotate(parents_lines[0], new_lines, new_revision_id,
-                                _left_matching_blocks):
-            yield data
+        lines = _reannotate(parents_lines[0], new_lines, new_revision_id,
+                            _left_matching_blocks)
+    elif len(parents_lines) == 2:
+        left = _reannotate(parents_lines[0], new_lines, new_revision_id,
+                           _left_matching_blocks)
+        right = _reannotate(parents_lines[1], new_lines, new_revision_id)
+        lines = []
+        for idx in xrange(len(new_lines)):
+            if left[idx][0] == right[idx][0]:
+                # The annotations match, just return the left one
+                lines.append(left[idx])
+            elif left[idx][0] == new_revision_id:
+                # The left parent claims a new value, return the right one
+                lines.append(right[idx])
+            elif right[idx][0] == new_revision_id:
+                # The right parent claims a new value, return the left one
+                lines.append(left[idx])
+            else:
+                # Both claim different origins
+                lines.append((new_revision_id, left[idx][1]))
     else:
-        block_list = [_left_matching_blocks] + [None] * len(parents_lines)
-        reannotations = [list(_reannotate(p, new_lines, new_revision_id, b))
-                         for p, b in zip(parents_lines, block_list)]
+        reannotations = [_reannotate(parents_lines[0], new_lines,
+                                     new_revision_id, _left_matching_blocks)]
+        reannotations.extend(_reannotate(p, new_lines, new_revision_id)
+                             for p in parents_lines[1:])
+        lines = []
         for annos in zip(*reannotations):
             origins = set(a for a, l in annos)
-            line = annos[0][1]
             if len(origins) == 1:
-                yield iter(origins).next(), line
-            elif len(origins) == 2 and new_revision_id in origins:
-                yield (x for x in origins if x != new_revision_id).next(), line
+                # All the parents agree, so just return the first one
+                lines.append(annos[0])
             else:
-                yield new_revision_id, line
+                line = annos[0][1]
+                if len(origins) == 2 and new_revision_id in origins:
+                    origins.remove(new_revision_id)
+                if len(origins) == 1:
+                    lines.append((origins.pop(), line))
+                else:
+                    lines.append((new_revision_id, line))
+    return lines
 
 
 def _reannotate(parent_lines, new_lines, new_revision_id,
@@ -197,9 +220,10 @@
         matcher = patiencediff.PatienceSequenceMatcher(None,
             plain_parent_lines, new_lines)
         matching_blocks = matcher.get_matching_blocks()
+    lines = []
     for i, j, n in matching_blocks:
         for line in new_lines[new_cur:j]:
-            yield new_revision_id, line
-        for data in parent_lines[i:i+n]:
-            yield data
+            lines.append((new_revision_id, line))
+        lines.extend(parent_lines[i:i+n])
         new_cur = j + n
+    return lines




More information about the bazaar-commits mailing list