Patchwork [2,of,2] obsolete: skip 'changectx' usage in unstable computation

login
register
mail settings
Submitter Pierre-Yves David
Date June 27, 2017, 11:01 a.m.
Message ID <2f755b1ced6b3752a0c4.1498561282@nodosa.octopoid.net>
Download mbox | patch
Permalink /patch/21768/
State Accepted
Headers show

Comments

Pierre-Yves David - June 27, 2017, 11:01 a.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@octobus.net>
# Date 1497827291 -7200
#      Mon Jun 19 01:08:11 2017 +0200
# Node ID 2f755b1ced6b3752a0c42e9aa08b28dbda21b1b9
# Parent  e7f139a172c2075ce88764938ea4c102ef87935f
# EXP-Topic bettertroubles
# Available At https://www.mercurial-scm.org/repo/users/marmoute/mercurial/
#              hg pull https://www.mercurial-scm.org/repo/users/marmoute/mercurial/ -r 2f755b1ced6b
obsolete: skip 'changectx' usage in unstable computation

We simplify the unstable computation code, skipping the expensive creation of
changectx object. We focus on efficient set operation and revnumber centric
functions.

In my mercurial development repository, this provides a 3x speedup to the
function:

  before: 5.319 ms
  after:  1.844 ms

repo details:

  total changesets:       40886
  obsolete changesets:     7756
  mutable (not obsolete):   293
  unstable:                  30

Patch

diff --git a/mercurial/obsolete.py b/mercurial/obsolete.py
--- a/mercurial/obsolete.py
+++ b/mercurial/obsolete.py
@@ -1325,16 +1325,18 @@  def _computeobsoleteset(repo):
 @cachefor('unstable')
 def _computeunstableset(repo):
     """the set of non obsolete revisions with obsolete parents"""
-    revs = [(ctx.rev(), ctx) for ctx in
-            repo.set('(not public()) and (not obsolete())')]
-    revs.sort(key=lambda x:x[0])
+    pfunc = repo.changelog.parentrevs
+    mutable = _mutablerevs(repo)
+    obsolete = getrevs(repo, 'obsolete')
+    others = mutable - obsolete
     unstable = set()
-    for rev, ctx in revs:
+    for r in sorted(others):
         # A rev is unstable if one of its parent is obsolete or unstable
         # this works since we traverse following growing rev order
-        if any((x.obsolete() or (x.rev() in unstable))
-                for x in ctx.parents()):
-            unstable.add(rev)
+        for p in pfunc(r):
+            if p in obsolete or p in unstable:
+                unstable.add(r)
+                break
     return unstable
 
 @cachefor('suspended')