Rev 3303: Optimize log --short/--line in the common case (abentley) in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Tue Mar 25 07:01:15 GMT 2008


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

------------------------------------------------------------
revno: 3303
revision-id:pqm at pqm.ubuntu.com-20080325070104-4k2nyfye5v0sublz
parent: pqm at pqm.ubuntu.com-20080323231145-nh7pyfd19alqp471
parent: aaron at aaronbentley.com-20080325052538-kvkms30yiknobig7
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Tue 2008-03-25 07:01:04 +0000
message:
  Optimize log --short/--line in the common case (abentley)
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
    ------------------------------------------------------------
    revno: 3302.1.5
    revision-id:aaron at aaronbentley.com-20080325052538-kvkms30yiknobig7
    parent: aaron at aaronbentley.com-20080324142315-e18xe0xgur76xbql
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: show_log
    timestamp: Tue 2008-03-25 01:25:38 -0400
    message:
      Update NEWS
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
    ------------------------------------------------------------
    revno: 3302.1.4
    revision-id:aaron at aaronbentley.com-20080324142315-e18xe0xgur76xbql
    parent: aaron at aaronbentley.com-20080324142038-kve58bcu069f6z58
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: fast-log
    timestamp: Mon 2008-03-24 10:23:15 -0400
    message:
      Return revno as a string
    modified:
      bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
    ------------------------------------------------------------
    revno: 3302.1.3
    revision-id:aaron at aaronbentley.com-20080324142038-kve58bcu069f6z58
    parent: aaron at aaronbentley.com-20080324140320-l46lss2a0khz9iqt
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: fast-log
    timestamp: Mon 2008-03-24 10:20:38 -0400
    message:
      Add optimization of the simple case of generating view revisions
    modified:
      bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
    ------------------------------------------------------------
    revno: 3302.1.2
    revision-id:aaron at aaronbentley.com-20080324140320-l46lss2a0khz9iqt
    parent: aaron at aaronbentley.com-20080324132642-fddmh8rwk9py3uxm
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: fast-log
    timestamp: Mon 2008-03-24 10:03:20 -0400
    message:
      Split out the major view_revision calculation logic
    modified:
      bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
    ------------------------------------------------------------
    revno: 3302.1.1
    revision-id:aaron at aaronbentley.com-20080324132642-fddmh8rwk9py3uxm
    parent: pqm at pqm.ubuntu.com-20080323231145-nh7pyfd19alqp471
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: fast-log
    timestamp: Mon 2008-03-24 09:26:42 -0400
    message:
      Split out _iter_revision, allow view_revisions to be an iterator
    modified:
      bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
=== modified file 'NEWS'
--- a/NEWS	2008-03-23 23:11:45 +0000
+++ b/NEWS	2008-03-25 05:25:38 +0000
@@ -24,16 +24,19 @@
 
   IMPROVEMENTS:
 
+    * Diff is now more specific about execute-bit changes it describes
+      (Chad Miller)
+
     * Fetching data over HTTP is a bit faster when urllib is used.  This is done
       by forcing it to recv 64k at a time when reading lines in HTTP headers,
       rather than just 1 byte at a time.  (Andrew Bennetts)
 
+    * Log --short and --line are much faster when -r is not specified.
+      (Aaron Bentley)
+
     * Merge is faster.  We no longer check a file's existence unnecessarily
       when merging the execute bit.  (Aaron Bentley)
 
-    * Diff is now more specific about execute-bit changes it describes
-      (Chad Miller)
-
   BUGFIXES:
 
     * ``bzr mv a b`` can be now used also to rename previously renamed

=== modified file 'bzrlib/log.py'
--- a/bzrlib/log.py	2008-03-23 20:06:17 +0000
+++ b/bzrlib/log.py	2008-03-24 14:23:15 +0000
@@ -188,6 +188,7 @@
     finally:
         branch.unlock()
 
+
 def _show_log(branch,
              lf,
              specific_fileid=None,
@@ -203,27 +204,65 @@
 
     if specific_fileid:
         mutter('get log for file_id %r', specific_fileid)
-
+    generate_merge_revisions = getattr(lf, 'supports_merge_revisions', False)
+    allow_single_merge_revision = getattr(lf,
+        'supports_single_merge_revision', False)
+    view_revisions = calculate_view_revisions(branch, start_revision,
+                                              end_revision, direction,
+                                              specific_fileid,
+                                              generate_merge_revisions,
+                                              allow_single_merge_revision)
     if search is not None:
         searchRE = re.compile(search, re.IGNORECASE)
     else:
         searchRE = None
 
+    rev_tag_dict = {}
+    generate_tags = getattr(lf, 'supports_tags', False)
+    if generate_tags:
+        if branch.supports_tags():
+            rev_tag_dict = branch.tags.get_reverse_tag_dict()
+
+    generate_delta = verbose and getattr(lf, 'supports_delta', False)
+
+    # now we just print all the revisions
+    log_count = 0
+    for (rev_id, revno, merge_depth), rev, delta in _iter_revisions(
+        branch.repository, view_revisions, generate_delta):
+        if searchRE:
+            if not searchRE.search(rev.message):
+                continue
+
+        lr = LogRevision(rev, revno, merge_depth, delta,
+                         rev_tag_dict.get(rev_id))
+        lf.log_revision(lr)
+        if limit:
+            log_count += 1
+            if log_count >= limit:
+                break
+
+
+def calculate_view_revisions(branch, start_revision, end_revision, direction,
+                             specific_fileid, generate_merge_revisions,
+                             allow_single_merge_revision):
+    if (not generate_merge_revisions and start_revision is end_revision is
+        None and direction == 'reverse' and specific_fileid is None):
+        return _linear_view_revisions(branch)
+
     mainline_revs, rev_nos, start_rev_id, end_rev_id = \
         _get_mainline_revs(branch, start_revision, end_revision)
     if not mainline_revs:
-        return
+        return []
 
     if direction == 'reverse':
         start_rev_id, end_rev_id = end_rev_id, start_rev_id
-        
-    generate_merge_revisions = getattr(lf, 'supports_merge_revisions', False)
+
     generate_single_revision = False
     if ((not generate_merge_revisions)
         and ((start_rev_id and (start_rev_id not in rev_nos))
             or (end_rev_id and (end_rev_id not in rev_nos)))):
         generate_single_revision = ((start_rev_id == end_rev_id)
-            and getattr(lf, 'supports_single_merge_revision', False))
+            and allow_single_merge_revision)
         if not generate_single_revision:
             raise BzrCommandError('Selected log formatter only supports '
                 'mainline revisions.')
@@ -247,48 +286,35 @@
         min_depth = min([d for r,n,d in view_revisions])
         if min_depth != 0:
             view_revisions = [(r,n,d-min_depth) for r,n,d in view_revisions]
-        
-    rev_tag_dict = {}
-    generate_tags = getattr(lf, 'supports_tags', False)
-    if generate_tags:
-        if branch.supports_tags():
-            rev_tag_dict = branch.tags.get_reverse_tag_dict()
-
-    generate_delta = verbose and getattr(lf, 'supports_delta', False)
-
-    def iter_revisions():
+    return view_revisions
+
+
+def _linear_view_revisions(branch):
+    start_revno, start_revision_id = branch.last_revision_info()
+    repo = branch.repository
+    revision_ids = repo.iter_reverse_revision_history(start_revision_id)
+    for num, revision_id in enumerate(revision_ids):
+        yield revision_id, str(start_revno - num), 0
+
+
+def _iter_revisions(repository, view_revisions, generate_delta):
+    num = 9
+    view_revisions = iter(view_revisions)
+    while True:
+        cur_view_revisions = [d for x, d in zip(range(num), view_revisions)]
+        if len(cur_view_revisions) == 0:
+            break
+        cur_deltas = {}
         # r = revision, n = revno, d = merge depth
-        revision_ids = [r for r, n, d in view_revisions]
-        num = 9
-        repository = branch.repository
-        while revision_ids:
-            cur_deltas = {}
-            revisions = repository.get_revisions(revision_ids[:num])
-            if generate_delta:
-                deltas = repository.get_deltas_for_revisions(revisions)
-                cur_deltas = dict(izip((r.revision_id for r in revisions),
-                                       deltas))
-            for revision in revisions:
-                yield revision, cur_deltas.get(revision.revision_id)
-            revision_ids  = revision_ids[num:]
-            num = min(int(num * 1.5), 200)
-
-    # now we just print all the revisions
-    log_count = 0
-    for ((rev_id, revno, merge_depth), (rev, delta)) in \
-         izip(view_revisions, iter_revisions()):
-
-        if searchRE:
-            if not searchRE.search(rev.message):
-                continue
-
-        lr = LogRevision(rev, revno, merge_depth, delta,
-                         rev_tag_dict.get(rev_id))
-        lf.log_revision(lr)
-        if limit:
-            log_count += 1
-            if log_count >= limit:
-                break
+        revision_ids = [r for (r, n, d) in cur_view_revisions]
+        revisions = repository.get_revisions(revision_ids)
+        if generate_delta:
+            deltas = repository.get_deltas_for_revisions(revisions)
+            cur_deltas = dict(izip((r.revision_id for r in revisions),
+                                   deltas))
+        for view_data, revision in izip(cur_view_revisions, revisions):
+            yield view_data, revision, cur_deltas.get(revision.revision_id)
+        num = min(int(num * 1.5), 200)
 
 
 def _get_mainline_revs(branch, start_revision, end_revision):




More information about the bazaar-commits mailing list