# HG changeset patch # User Pierre-Yves David # Date 2017-06-18 23:08:11 # Node ID 31ab1912678a8262ff57414c57c08dd1ce248ce8 # Parent 765c6ab07a88e9eb9c2eb59a9d0a900ae451dc05 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 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')