[PATCH 3 of 3] revset: make use of natively computed set for 'draft()' and 'secret()'

Pierre-Yves David pierre-yves.david at ens-lyon.org
Thu Jun 18 12:05:22 CDT 2015


# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at fb.com>
# Date 1433989131 25200
#      Wed Jun 10 19:18:51 2015 -0700
# Node ID e0d29cae67f9ad7324fc4818bed2248aeef0af83
# Parent  77ad3d42d8fa78b13f19683512f913185a9d4fb9
revset: make use of natively computed set for 'draft()' and 'secret()'

If the computation of set for each face (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 performances 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%

diff --git a/contrib/all-revsets.txt b/contrib/all-revsets.txt
--- a/contrib/all-revsets.txt
+++ b/contrib/all-revsets.txt
@@ -122,5 +122,9 @@ roots((0::) - (0::tip))
 # Testing the behavior of "head()" in various situations
 head()
 head() - public()
 draft() and head()
 head() and author("mpm")
+
+# testing the mutable phases set
+draft()
+secret()
diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -1462,13 +1462,20 @@ def parents(repo, subset, x):
     ps -= set([node.nullrev])
     return subset & ps
 
 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()``
     Changeset in draft phase."""
     # i18n: "draft" is a keyword


More information about the Mercurial-devel mailing list