[PATCH 1 of 2 V3] changelog: prefilter in headrevs()

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCH 1 of 2 V3] changelog: prefilter in headrevs()

Georges Racinet-2
# HG changeset patch
# User Georges Racinet <[hidden email]>
# Date 1550659746 -3600
#      Wed Feb 20 11:49:06 2019 +0100
# Node ID 1c1f122821291657b33b447e89dc4420b3f833b5
# Parent  0c7b353ce100e9125251f4ae37a8739242ce537c
# EXP-Topic revset.predicates
changelog: prefilter in headrevs()

In case where headrevs() is called on some revisions, we perform
the check that aren't filtered in advance, and switch revlog to
use its unchecked form.

This allows to work with alternative implementations that don't have knowledge
of the filtering system, such as the Rust one.

diff -r 0c7b353ce100 -r 1c1f12282129 mercurial/changelog.py
--- a/mercurial/changelog.py Thu Jan 10 18:25:18 2019 +0100
+++ b/mercurial/changelog.py Wed Feb 20 11:49:06 2019 +0100
@@ -22,6 +22,7 @@
     error,
     pycompat,
     revlog,
+    util,
 )
 from .utils import (
     dateutil,
@@ -350,6 +351,27 @@
     def reachableroots(self, minroot, heads, roots, includepath=False):
         return self.index.reachableroots2(minroot, heads, roots, includepath)
 
+    def _checknofilteredinrevs(self, revs):
+        """raise the appropriate error if 'revs' contains a filtered revision
+
+        This returns a version of 'revs' to be used thereafter by the caller.
+        In particular, if revs is an iterator, it is converted into a set.
+        """
+        safehasattr = util.safehasattr
+        if safehasattr(revs, '__next__'):
+            # Note that inspect.isgenerator() is not true for iterators,
+            revs = set(revs)
+
+        filteredrevs = self.filteredrevs
+        if safehasattr(revs, 'first'):  # smartset
+            offenders = revs & filteredrevs
+        else:
+            offenders = filteredrevs.intersection(revs)
+
+        for rev in offenders:
+            raise error.FilteredIndexError(rev)
+        return revs
+
     def headrevs(self, revs=None):
         if revs is None and self.filteredrevs:
             try:
@@ -359,6 +381,8 @@
             except AttributeError:
                 return self._headrevs()
 
+        if self.filteredrevs:
+            revs = self._checknofilteredinrevs(revs)
         return super(changelog, self).headrevs(revs)
 
     def strip(self, *args, **kwargs):
diff -r 0c7b353ce100 -r 1c1f12282129 mercurial/revlog.py
--- a/mercurial/revlog.py Thu Jan 10 18:25:18 2019 +0100
+++ b/mercurial/revlog.py Wed Feb 20 11:49:06 2019 +0100
@@ -1121,7 +1121,7 @@
                 return self.index.headrevs()
             except AttributeError:
                 return self._headrevs()
-        return dagop.headrevs(revs, self.parentrevs)
+        return dagop.headrevs(revs, self._uncheckedparentrevs)
 
     def computephases(self, roots):
         return self.index.computephasesmapsets(roots)
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

[PATCH 2 of 2 V3] rust-cpython: using rustext.dagop.headrevs in revlog

Georges Racinet-2
# HG changeset patch
# User Georges Racinet <[hidden email]>
# Date 1547651966 -3600
#      Wed Jan 16 16:19:26 2019 +0100
# Node ID 2f378c55646d0fea1d18877774b7a963ebd2aadf
# Parent  1c1f122821291657b33b447e89dc4420b3f833b5
# EXP-Topic revset.predicates
rust-cpython: using rustext.dagop.headrevs in revlog

As with the previous oxidation series, revlog plays the role
of the factory, either using its parents function, or passing the
index.

We include below results of revsetbenchmarks.py taken on the
PyPy repository on those of contrib/all-revsets.tx that involve
`heads()`.

In most of the cases, this seems to be either neutral or an improvement.
In the cases where it's actually a bit slower, we suspect that differences
in `heads()` performance is actually burried in variance on the incoming
revset (probably several orders of magnitude slower).

The precheck for filtered revisions of parent changeset has a significative
performance benefit, too.

Result by revset
================

Revision:
0) 0c7b353ce100; rust-cpython: binding for headrevs()
1) Parent of this changeset; changelog: prefilter in headrevs()
2) This changeset


revset #0: heads(commonancestors(last(head(), 2)))
   plain         min           max           first         last          reverse       rev..rst      rev..ast      sort          sor..rst      sor..ast
0) 0.001379      0.001361      0.001381      0.001410      0.001393      0.001372      0.001414      0.001387      0.001411      0.001429      0.001415
1) 0.001351      0.001373      0.001383      0.001392      0.001401      0.001385      0.001405      0.001406      0.001385      0.001424      0.001399
2) 0.001365      0.001362      0.001375      0.001393      0.001370      0.001365      0.001413      0.001386      0.001377      0.001415      0.001411

revset #1: heads(commonancestors(head()))
   plain         min           max           first         last          reverse       rev..rst      rev..ast      sort          sor..rst      sor..ast
0) 0.047578      0.048578      0.047764      0.048065      0.047289      0.047305      0.047729      0.047370      0.047611      0.048005      0.047755
1) 0.048072      0.047471      0.048351      0.048193      0.048380      0.047968      0.047683      0.047355      0.048587      0.047044      0.048299
2) 0.047124      0.046699      0.046896      0.047250      0.046920      0.047379      0.046855      0.047753      0.047289      0.047219      0.046991

revset #2: heads(all())
   plain         min           max           first         last          reverse       rev..rst      rev..ast      sort          sor..rst      sor..ast
0) 0.037654      0.037814      0.037149      0.037457      0.037609      0.037053      0.036825      0.037054      0.037739      0.036816      0.037604
1) 0.021845  58% 0.022172  58% 0.022148  59% 0.022059  58% 0.022261  59% 0.022246  60% 0.021691  58% 0.021967  59% 0.022156  58% 0.021820  59% 0.023141  61%
2) 0.014459  66% 0.014470  65% 0.014420  65% 0.014413  65% 0.014421  64% 0.014492  65% 0.014512  66% 0.014579  66% 0.014500  65% 0.014501  66% 0.014537  62%

revset #3: heads(-10000:-1)
   plain         min           max           first         last          reverse       rev..rst      rev..ast      sort          sor..rst      sor..ast
0) 0.003696      0.003681      0.003719      0.003746      0.003725      0.003750      0.003692      0.003747      0.003712      0.003754      0.003763
1) 0.002131  57% 0.002142  58% 0.002147  57% 0.002203  58% 0.002143  57% 0.002208  58% 0.002158  58% 0.002182  58% 0.002169  58% 0.002209  58% 0.002201  58%
2) 0.001490  69% 0.001524  71% 0.001515  70% 0.001528  69% 0.001531  71% 0.001520  68% 0.001549  71% 0.001542  70% 0.001560  71% 0.001559  70% 0.001544  70%

revset #4: (-5000:-1000) and heads(-10000:-1)
   plain         min           max           first         last          reverse       rev..rst      rev..ast      sort          sor..rst      sor..ast
0) 0.003832      0.003816      0.003747      0.003814      0.003749      0.003894      0.003784      0.003796      0.003915      0.003829      0.003795
1) 0.002282  59% 0.002208  57% 0.002220  59% 0.002240  58% 0.002210  58% 0.002276  58% 0.002250  59% 0.002250  59% 0.002311  59% 0.002230  58% 0.002241  59%
2) 0.001658  72% 0.001662  75% 0.001568  70% 0.001599  71% 0.001588  71% 0.001696  74% 0.001615  71% 0.001593  70% 0.001710  73% 0.001622  72% 0.001616  72%

revset #5: heads(matching(tip, "author"))
   plain         min           max           first         last          reverse       rev..rst      rev..ast      sort          sor..rst      sor..ast
0) 7.826449      7.563260      7.581034      7.688493      7.634001      7.777860      7.768228      8.026097      7.767422      7.565254      7.938643
1) 7.750766      7.562555      7.660426      7.574089      7.492220      7.438582      7.562015      7.530635  93% 7.636343      7.636712      7.645113
2) 7.617941      7.519601      7.584922      7.507653      7.547440      7.524436      7.575291      7.883991      7.792142      7.709622      7.868595

revset #6: heads(matching(tip, "author")) and -10000:-1
   plain         min           max           first         last          reverse       rev..rst      rev..ast      sort          sor..rst      sor..ast
0) 7.744489      7.728684      7.734065      7.928513      7.875949      7.883727      7.815492      7.791335      7.784793      7.761218      7.815731
1) 7.808956      7.480446      7.618759      7.920270      7.676343      7.803613      7.770210      7.713100      7.584420      7.767335      7.825140
2) 7.519987      7.938748 106% 7.805328      7.694162      7.750129      7.714229      7.603825      7.580734      7.555291      7.524207      7.504580

revset #7: (-10000:-1) and heads(matching(tip, "author"))
   plain         min           max           first         last          reverse       rev..rst      rev..ast      sort          sor..rst      sor..ast
0) 7.909321      7.694357      7.666021      7.538686      7.771821      7.876217      7.852103      7.812727      7.545919      7.788860      7.764585
1) 7.749232      7.683715      7.968393      7.895257      7.764160      8.314884 105% 7.921697      7.882613      7.867209      7.684707      7.544501
2) 7.824903      7.784605      7.727846      7.566613      7.581994      7.539205  90% 7.555316      7.535572      7.581786      7.901795      7.662832

diff -r 1c1f12282129 -r 2f378c55646d mercurial/revlog.py
--- a/mercurial/revlog.py Wed Feb 20 11:49:06 2019 +0100
+++ b/mercurial/revlog.py Wed Jan 16 16:19:26 2019 +0100
@@ -1121,6 +1121,8 @@
                 return self.index.headrevs()
             except AttributeError:
                 return self._headrevs()
+        if rustext is not None:
+            return rustext.dagop.headrevs(self.index, revs)
         return dagop.headrevs(revs, self._uncheckedparentrevs)
 
     def computephases(self, roots):
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 1 of 2 V3] changelog: prefilter in headrevs()

Yuya Nishihara
In reply to this post by Georges Racinet-2
On Thu, 21 Feb 2019 11:27:24 +0100, Georges Racinet wrote:
> # HG changeset patch
> # User Georges Racinet <[hidden email]>
> # Date 1550659746 -3600
> #      Wed Feb 20 11:49:06 2019 +0100
> # Node ID 1c1f122821291657b33b447e89dc4420b3f833b5
> # Parent  0c7b353ce100e9125251f4ae37a8739242ce537c
> # EXP-Topic revset.predicates
> changelog: prefilter in headrevs()

Queued, thanks.
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel