revset: make use of natively-computed set for 'draft()' and 'secret()'
If the computation of a set for each phase (done in C) is available,
we use it directly instead of applying a simple filter. This give a
massive speed-up in the vast majority of cases.
On my mercurial repo with about 15000 out of 40000 draft changesets:
revset: draft()
plain min first last
0) 0.011201 0.019950 0.009844 0.000074
1) 0.000284 2% 0.000312 1% 0.000314 3% 0.000315 x4.3
Bad performance for "last" come from the handling of the 15000 elements set
(memory allocation, filtering hidden changesets (99% of it) etc. compared to
applying the filter only on a handfuld of revisions (the first draft changesets
being close of tip).
This is not seen as an issue since:
* Timing is still pretty good and in line with all the other one,
* Current user of Vanilla Mercurial will not have 1/3 of their repo draft,
This bad effect disappears when phase's set is smaller. (about 200 secrets):
revset: secret()
plain min first last
0) 0.011181 0.022228 0.010851 0.000452
1) 0.000058 0% 0.000084 0% 0.000087 0% 0.000087 19%
--- a/contrib/all-revsets.txt Wed Jun 17 19:19:57 2015 -0700
+++ b/contrib/all-revsets.txt Wed Jun 10 19:18:51 2015 -0700
@@ -124,3 +124,7 @@
head() - public()
draft() and head()
head() and author("mpm")
+
+# testing the mutable phases set
+draft()
+secret()
--- a/mercurial/revset.py Wed Jun 17 19:19:57 2015 -0700
+++ b/mercurial/revset.py Wed Jun 10 19:18:51 2015 -0700
@@ -1464,9 +1464,16 @@
def _phase(repo, subset, target):
"""helper to select all rev in phase <target>"""
- phase = repo._phasecache.phase
- condition = lambda r: phase(repo, r) == target
- return subset.filter(condition, cache=False)
+ repo._phasecache.loadphaserevs(repo) # ensure phase's sets are loaded
+ if repo._phasecache._phasesets:
+ s = repo._phasecache._phasesets[target] - repo.changelog.filteredrevs
+ s = baseset(s)
+ s.sort() # set are non ordered, so we enforce ascending
+ return subset & s
+ else:
+ phase = repo._phasecache.phase
+ condition = lambda r: phase(repo, r) == target
+ return subset.filter(condition, cache=False)
def draft(repo, subset, x):
"""``draft()``