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)
#!/usr/bin/env python
"""
Tests the behavior of filelog w.r.t. data starting with '\1\n'
"""
from __future__ import absolute_import, print_function
from mercurial.node import (
hex,
nullid,
)
from mercurial import (
hg,
ui as uimod,
)
myui = uimod.ui()
repo = hg.repository(myui, path='.', create=True)
fl = repo.file('foobar')
def addrev(text, renamed=False):
if renamed:
# data doesn't matter. Just make sure filelog.renamed() returns True
meta = {'copyrev': hex(nullid), 'copy': 'bar'}
else:
meta = {}
lock = t = None
try:
lock = repo.lock()
t = repo.transaction('commit')
node = fl.add(text, meta, t, 0, nullid, nullid)
return node
finally:
if t:
t.close()
if lock:
lock.release()
def error(text):
print('ERROR: ' + text)
textwith = '\1\nfoo'
without = 'foo'
node = addrev(textwith)
if not textwith == fl.read(node):
error('filelog.read for data starting with \\1\\n')
if fl.cmp(node, textwith) or not fl.cmp(node, without):
error('filelog.cmp for data starting with \\1\\n')
if fl.size(0) != len(textwith):
error('FIXME: This is a known failure of filelog.size for data starting '
'with \\1\\n')
node = addrev(textwith, renamed=True)
if not textwith == fl.read(node):
error('filelog.read for a renaming + data starting with \\1\\n')
if fl.cmp(node, textwith) or not fl.cmp(node, without):
error('filelog.cmp for a renaming + data starting with \\1\\n')
if fl.size(1) != len(textwith):
error('filelog.size for a renaming + data starting with \\1\\n')
print('OK.')