Patchwork [STABLE] phases: break advanceboundary revset call in multiple piece (issue4371)

login
register
mail settings
Submitter Pierre-Yves David
Date Sept. 18, 2014, 5:12 a.m.
Message ID <380ecd77411644f4de22.1411017149@marginatus.alto.octopoid.net>
Download mbox | patch
Permalink /patch/5865/
State Superseded
Headers show

Comments

Pierre-Yves David - Sept. 18, 2014, 5:12 a.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@fb.com>
# Date 1411014729 25200
#      Wed Sep 17 21:32:09 2014 -0700
# Branch stable
# Node ID 380ecd77411644f4de226848bd4cac4c18d809a1
# Parent  4bbcee186fc64e39c51f90e8256466885a3a4d65
phases: break advanceboundary revset call in multiple piece (issue4371)

The current revset is massively slow on huge repo (5 minutes for Mozilla
central). This slowness originate from issue4352, but solving it is too big for
stable.

Instead we do multiple small revset call and manual handling of some of the
operation. This bring back the phase movement to unnoticeable sub second time.
Pierre-Yves David - Sept. 18, 2014, 6 a.m.
On 09/17/2014 10:12 PM, Pierre-Yves David wrote:
> # HG changeset patch
> # User Pierre-Yves David <pierre-yves.david@fb.com>
> # Date 1411014729 25200
> #      Wed Sep 17 21:32:09 2014 -0700
> # Branch stable
> # Node ID 380ecd77411644f4de226848bd4cac4c18d809a1
> # Parent  4bbcee186fc64e39c51f90e8256466885a3a4d65
> phases: break advanceboundary revset call in multiple piece (issue4371)

Actually, I just found out that a single and trivial diff on my huge 
stack is getting this to acceptable performance. So this hack is not as 
necessary (but probably still a bit faster).

Patch

diff --git a/mercurial/phases.py b/mercurial/phases.py
--- a/mercurial/phases.py
+++ b/mercurial/phases.py
@@ -219,12 +219,20 @@  class phasecache(object):
             nodes = [n for n in nodes
                      if self.phase(repo, repo[n].rev()) >= phase]
             if not nodes:
                 break # no roots to move anymore
             olds = self.phaseroots[phase]
-            roots = set(ctx.node() for ctx in repo.set(
-                    'roots((%ln::) - (%ln::%ln))', olds, olds, nodes))
+            # We use multiple revset calls to workaround issue4352
+            #
+            # This is a stable hotfix for issue4371
+            # At some point we will hopefully be able to got back to:
+            #
+            #     repo.set('roots((%ln::) - (%ln::%ln))', olds, olds, nodes)
+            rset = set(repo.revs('%ln::', olds))
+            rset -= set(repo.revs('%ln::%ln', olds, nodes))
+            rset = repo.set('roots(%ld)', rset)
+            roots = set(ctx.node() for ctx in rset)
             if olds != roots:
                 self._updateroots(phase, roots)
                 # some roots may need to be declared for lower phases
                 delroots.extend(olds - roots)
             # declare deleted root in the target phase