Patchwork [7,of,8,V2] perf: start from an existing branchmap if possible

login
register
mail settings
Submitter Boris Feld
Date Nov. 26, 2018, 6:44 p.m.
Message ID <41772e57bfc92d38899b.1543257878@localhost.localdomain>
Download mbox | patch
Permalink /patch/36798/
State Accepted
Headers show

Comments

Boris Feld - Nov. 26, 2018, 6:44 p.m.
# HG changeset patch
# User Boris Feld <boris.feld@octobus.net>
# Date 1542834707 0
#      Wed Nov 21 21:11:47 2018 +0000
# Node ID 41772e57bfc92d38899b24f729d992c39dc32473
# Parent  03c3522ed8a678695eba5a0dc7612236fbdfb47b
# EXP-Topic perf-branchmap
# Available At https://bitbucket.org/octobus/mercurial-devel/
#              hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 41772e57bfc9
perf: start from an existing branchmap if possible

If the --base set if a superset of one of the cached branchmap, we should use as
a starting point. This greatly help the overall runtime of
`hg perfbranchmapupdate`

For example, for a repository with about 500 000 revisions, using this trick
make the command runtime move from about 200 second to about 10 seconds. A 20x
gain.

Patch

diff --git a/contrib/perf.py b/contrib/perf.py
--- a/contrib/perf.py
+++ b/contrib/perf.py
@@ -2296,8 +2296,22 @@  def perfbranchmapupdate(ui, repo, base=(
         baserepo = repo.filtered('__perf_branchmap_update_base')
         targetrepo = repo.filtered('__perf_branchmap_update_target')
 
-        base = branchmap.branchcache()
-        base.update(baserepo, allbaserevs)
+        # try to find an existing branchmap to reuse
+        subsettable = getbranchmapsubsettable()
+        candidatefilter = subsettable.get(None)
+        while candidatefilter is not None:
+            candidatebm = repo.filtered(candidatefilter).branchmap()
+            if candidatebm.validfor(baserepo):
+                filtered = repoview.filterrevs(repo, candidatefilter)
+                missing = [r for r in allbaserevs if r in filtered]
+                base = candidatebm.copy()
+                base.update(baserepo, missing)
+                break
+            candidatefilter = subsettable.get(candidatefilter)
+        else:
+            # no suitable subset where found
+            base = branchmap.branchcache()
+            base.update(baserepo, allbaserevs)
 
         def setup():
             x[0] = base.copy()