obsolete: speed up unstable computation
authorLaurent Charignon <lcharignon@fb.com>
Tue, 28 Apr 2015 16:51:23 -0700
changeset 24928 876a2ebfbf4f
parent 24927 cd0068232ec0
child 24929 6fb98463643b
obsolete: speed up unstable computation Speed up the computation of the unstable revset by using the not public() revset. In another series of patches, we optimize the not public() revset and together it leads to a 50-100x speedup on the computation of unstable() for our big repos.
mercurial/obsolete.py
--- a/mercurial/obsolete.py	Fri Apr 24 14:46:30 2015 -0700
+++ b/mercurial/obsolete.py	Tue Apr 28 16:51:23 2015 -0700
@@ -1110,13 +1110,17 @@
 @cachefor('unstable')
 def _computeunstableset(repo):
     """the set of non obsolete revisions with obsolete parents"""
-    # revset is not efficient enough here
-    # we do (obsolete()::) - obsolete() by hand
-    obs = getrevs(repo, 'obsolete')
-    if not obs:
-        return set()
-    cl = repo.changelog
-    return set(r for r in cl.descendants(obs) if r not in obs)
+    revs = [(ctx.rev(), ctx) for ctx in
+            repo.set('(not public()) and (not obsolete())')]
+    revs.sort(key=lambda x:x[0])
+    unstable = set()
+    for rev, ctx in revs:
+        # A rev is unstable if one of its parent is obsolete or unstable
+        # this works since we traverse following growing rev order
+        if util.any((x.obsolete() or (x.rev() in unstable))
+                for x in ctx.parents()):
+            unstable.add(rev)
+    return unstable
 
 @cachefor('suspended')
 def _computesuspendedset(repo):