changeset 24928:876a2ebfbf4f

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.
author Laurent Charignon <lcharignon@fb.com>
date Tue, 28 Apr 2015 16:51:23 -0700
parents cd0068232ec0
children 6fb98463643b
files mercurial/obsolete.py
diffstat 1 files changed, 11 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- 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):