Patchwork [09,of,13] perf: add a `perfbranchmapupdate` command

login
register
mail settings
Submitter Boris Feld
Date Nov. 23, 2018, 2:09 p.m.
Message ID <d9447d83339527ab8225.1542982145@localhost.localdomain>
Download mbox | patch
Permalink /patch/36738/
State Accepted
Headers show

Comments

Boris Feld - Nov. 23, 2018, 2:09 p.m.
# HG changeset patch
# User Boris Feld <boris.feld@octobus.net>
# Date 1542801745 0
#      Wed Nov 21 12:02:25 2018 +0000
# Node ID d9447d83339527ab8225b13e7a518fe4118ba947
# Parent  1ab87863dc79a8e3139c723e83bef8c1ce107016
# EXP-Topic perf-branchmap
# Available At https://bitbucket.org/octobus/mercurial-devel/
#              hg pull https://bitbucket.org/octobus/mercurial-devel/ -r d9447d833395
perf: add a `perfbranchmapupdate` command

This command benchmark the time necessary to update the branchmap between two
sets of revisions. This changeset introduce a first version, doing nothing fancy
regarding cache or other internal details.

Patch

diff --git a/contrib/perf.py b/contrib/perf.py
--- a/contrib/perf.py
+++ b/contrib/perf.py
@@ -2183,6 +2183,61 @@  def perfbranchmap(ui, repo, *filternames
         branchcachewrite.restore()
     fm.end()
 
+@command(b'perfbranchmapupdate', [
+     (b'', b'base', [], b'subset of revision to start from'),
+     (b'', b'target', [], b'subset of revision to end with'),
+    ] + formatteropts)
+def perfbranchmapupdate(ui, repo, base=(), target=(), **opts):
+    """benchmark branchmap update from for <base> revs to <target> revs
+
+    Examples:
+
+       # update for the one last revision
+       $ hg perfbranchmapupdate --base 'not tip' --target 'tip'
+
+       $ update for change coming with a new branch
+       $ hg perfbranchmapupdate --base 'stable' --target 'default'
+    """
+    from mercurial import branchmap
+    opts = _byteskwargs(opts)
+    timer, fm = gettimer(ui, opts)
+    x = [None] # used to pass data between closure
+
+    # we use a `list` here to avoid possible side effect from smartset
+    baserevs = list(scmutil.revrange(repo, base))
+    targetrevs = list(scmutil.revrange(repo, target))
+    if not baserevs:
+        raise error.Abort('no revisions selected for --base')
+    if not targetrevs:
+        raise error.Abort('no revisions selected for --target')
+
+    # make sure the target branchmap also contains the one in the base
+    targetrevs = list(set(baserevs) | set(targetrevs))
+    targetrevs.sort()
+
+    cl = repo.changelog
+    allbaserevs = list(cl.ancestors(baserevs, inclusive=True))
+    allbaserevs.sort()
+    alltargetrevs = frozenset(cl.ancestors(targetrevs, inclusive=True))
+
+    newrevs = list(alltargetrevs.difference(allbaserevs))
+    newrevs.sort()
+
+    msg = 'benchmark of branchmap with %d revisions with %d new ones\n'
+    ui.status(msg % (len(allbaserevs), len(newrevs)))
+
+    base = branchmap.branchcache()
+    base.update(repo, allbaserevs)
+
+    def setup():
+        x[0] = base.copy()
+
+    def bench():
+        x[0].update(repo, newrevs)
+
+    timer(bench, setup=setup)
+    fm.end()
+
 @command(b'perfbranchmapload', [
      (b'f', b'filter', b'', b'Specify repoview filter'),
      (b'', b'list', False, b'List brachmap filter caches'),
diff --git a/tests/test-contrib-perf.t b/tests/test-contrib-perf.t
--- a/tests/test-contrib-perf.t
+++ b/tests/test-contrib-perf.t
@@ -57,6 +57,9 @@  perfstatus
                  benchmark the update of a branchmap
    perfbranchmapload
                  benchmark reading the branchmap
+   perfbranchmapupdate
+                 benchmark branchmap update from for <base> revs to <target>
+                 revs
    perfbundleread
                  Benchmark reading of bundle files.
    perfcca       (no help text available)
@@ -141,6 +144,8 @@  perfstatus
   $ hg perfbookmarks
   $ hg perfbranchmap
   $ hg perfbranchmapload
+  $ hg perfbranchmapupdate --base "not tip" --target "tip"
+  benchmark of branchmap with 3 revisions with 1 new ones
   $ hg perfcca
   $ hg perfchangegroupchangelog
   $ hg perfchangeset 2