From patchwork Tue Sep 13 16:13:27 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [6,of,7] revset: fix order of nested 'or' expression (BC) From: Yuya Nishihara X-Patchwork-Id: 16607 Message-Id: <14af6142b21b0f3e3cf7.1473783207@mimosa> To: mercurial-devel@mercurial-scm.org Date: Wed, 14 Sep 2016 01:13:27 +0900 # HG changeset patch # User Yuya Nishihara # Date 1466932632 -32400 # Sun Jun 26 18:17:12 2016 +0900 # Node ID 14af6142b21b0f3e3cf742410d4e7adb92ff4c76 # Parent fbceee41a25ddcbb81c36489b0b6b183c5e9197f revset: fix order of nested 'or' expression (BC) This fixes the order of 'x & (y + z)' where 'y' and 'z' are not trivial. The follow-order 'or' operation is slower than the ordered operation if an input set is large: #0 #1 #2 #3 0) 0.002968 0.002980 0.002982 0.073042 1) 0.004513 0.004485 0.012029 0.075261 #0: 0:4000 & (0:1099 + 1000:2099 + 2000:3099) #1: 4000:0 & (0:1099 + 1000:2099 + 2000:3099) #2: 10000:0 & (0:1099 + 1000:2099 + 2000:3099) #3: file("path:hg") & (0:1099 + 1000:2099 + 2000:3099) I've tried another implementation, but which appeared to be slower than this version. ss = [getset(repo, fullreposet(repo), x) for x in xs] return subset.filter(lambda r: any(r in s for s in ss), cache=False) diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -407,7 +407,12 @@ def _orsetlist(repo, subset, xs): return a + b def orset(repo, subset, x, order): - return _orsetlist(repo, subset, getlist(x)) + xs = getlist(x) + if order == followorder: + # slow path to take the subset order + return subset & _orsetlist(repo, fullreposet(repo), xs) + else: + return _orsetlist(repo, subset, xs) def notset(repo, subset, x, order): return subset - getset(repo, subset, x) diff --git a/tests/test-revset.t b/tests/test-revset.t --- a/tests/test-revset.t +++ b/tests/test-revset.t @@ -1317,15 +1317,14 @@ ordering defined by it. follow) define) * set: - , + , - >, - > + >> + 2 + 1 0 - 1 - 2 - BROKEN: should be '2 1 0' '_intlist(a b)' should behave like 'a + b':