obsolete: skip 'changectx' usage in unstable computation
authorPierre-Yves David <pierre-yves.david@octobus.net>
Mon, 19 Jun 2017 01:08:11 +0200
changeset 33130 31ab1912678a
parent 33129 765c6ab07a88
child 33131 c2ca511c4771
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
mercurial/obsolete.py
--- a/mercurial/obsolete.py	Sun Jun 18 22:38:11 2017 +0200
+++ b/mercurial/obsolete.py	Mon Jun 19 01:08:11 2017 +0200
@@ -1325,16 +1325,18 @@
 @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')