fileset: reorder 'and' expression to evaluate basic patterns first
Timing of a crafted example (when disk cache is warm):
$ hg files set:'binary() and path:contrib'
(orig) time: real 0.140 secs (user 0.120+0.000 sys 0.020+0.000)
(new) time: real 0.040 secs (user 0.030+0.000 sys 0.010+0.000)
--- a/mercurial/filesetlang.py Sun Jul 22 11:47:29 2018 +0900
+++ b/mercurial/filesetlang.py Sat Jul 21 16:41:45 2018 +0900
@@ -184,7 +184,14 @@
if op == 'not':
w, t = _optimize(x[1])
return w, (op, t)
- if op in {'and', 'minus'}:
+ if op == 'and':
+ wa, ta = _optimize(x[1])
+ wb, tb = _optimize(x[2])
+ if wa <= wb:
+ return wa, (op, ta, tb)
+ else:
+ return wb, (op, tb, ta)
+ if op == 'minus':
wa, ta = _optimize(x[1])
wb, tb = _optimize(x[2])
return max(wa, wb), (op, ta, tb)
--- a/tests/test-fileset.t Sun Jul 22 11:47:29 2018 +0900
+++ b/tests/test-fileset.t Sat Jul 21 16:41:45 2018 +0900
@@ -186,18 +186,18 @@
(symbol 'a2')
(and
(func
- (symbol 'grep')
- (string 'b'))
+ (symbol 'clean')
+ None)
(func
- (symbol 'clean')
- None)))
+ (symbol 'grep')
+ (string 'b'))))
* matcher:
<unionmatcher matchers=[
<patternmatcher patterns='(?:a1$)'>,
<patternmatcher patterns='(?:a2$)'>,
<intersectionmatcher
- m1=<predicatenmatcher pred=grep('b')>,
- m2=<predicatenmatcher pred=clean>>]>
+ m1=<predicatenmatcher pred=clean>,
+ m2=<predicatenmatcher pred=grep('b')>>]>
a1
a2
b1
@@ -283,6 +283,19 @@
$ fileset 'binary()'
bin
+ $ fileset -p optimized -s 'binary() and b*'
+ * optimized:
+ (and
+ (symbol 'b*')
+ (func
+ (symbol 'binary')
+ None))
+ * matcher:
+ <intersectionmatcher
+ m1=<patternmatcher patterns='(?:b[^/]*$)'>,
+ m2=<predicatenmatcher pred=binary>>
+ bin
+
$ fileset 'grep("b{1}")'
.hgignore
b1