perf: support measuring bdiff for all changeset related data
authorGregory Szorc <gregory.szorc@gmail.com>
Sun, 06 Nov 2016 10:46:55 -0800
changeset 30337 6ecad4b73569
parent 30336 7ddc8f8d7712
child 30338 b0ca939414ea
perf: support measuring bdiff for all changeset related data The --all argument changes the behavior of `perfbdiff` to pull in fulltext revision pairs for all changes related to a changeset. The p1 and p2 manifests will be bdiffed against current. Every file that changed between p1 and current will have its file revisions loaded and bdiffed. This mode of operation effectively measured the bdiff time required for `hg commit`.
contrib/perf.py
--- a/contrib/perf.py	Sun Nov 06 11:01:25 2016 -0800
+++ b/contrib/perf.py	Sun Nov 06 10:46:55 2016 -0800
@@ -748,7 +748,8 @@
     fm.end()
 
 @command('perfbdiff', revlogopts + formatteropts + [
-    ('', 'count', 1, 'number of revisions to test (when using --startrev)')],
+    ('', 'count', 1, 'number of revisions to test (when using --startrev)'),
+    ('', 'alldata', False, 'test bdiffs for all associated revisions')],
     '-c|-m|FILE REV')
 def perfbdiff(ui, repo, file_, rev=None, count=None, **opts):
     """benchmark a bdiff between revisions
@@ -757,7 +758,14 @@
 
     With ``--count``, benchmark bdiffs between delta parents and self for N
     revisions starting at the specified revision.
+
+    With ``--alldata``, assume the requested revision is a changeset and
+    measure bdiffs for all changes related to that changeset (manifest
+    and filelogs).
     """
+    if opts['alldata']:
+        opts['changelog'] = True
+
     if opts.get('changelog') or opts.get('manifest'):
         file_, rev = None, file_
     elif rev is None:
@@ -769,8 +777,25 @@
 
     startrev = r.rev(r.lookup(rev))
     for rev in range(startrev, min(startrev + count, len(r) - 1)):
-        dp = r.deltaparent(rev)
-        textpairs.append((r.revision(dp), r.revision(rev)))
+        if opts['alldata']:
+            # Load revisions associated with changeset.
+            ctx = repo[rev]
+            mtext = repo.manifest.revision(ctx.manifestnode())
+            for pctx in ctx.parents():
+                pman = repo.manifest.revision(pctx.manifestnode())
+                textpairs.append((pman, mtext))
+
+            # Load filelog revisions by iterating manifest delta.
+            man = ctx.manifest()
+            pman = ctx.p1().manifest()
+            for filename, change in pman.diff(man).items():
+                fctx = repo.file(filename)
+                f1 = fctx.revision(change[0][0] or -1)
+                f2 = fctx.revision(change[1][0] or -1)
+                textpairs.append((f1, f2))
+        else:
+            dp = r.deltaparent(rev)
+            textpairs.append((r.revision(dp), r.revision(rev)))
 
     def d():
         for pair in textpairs: