Show More
@@ -50,6 +50,12 b' def kindpatmatch(mctx, x, y):' | |||||
50 | return stringmatch(mctx, _getkindpat(x, y, matchmod.allpatternkinds, |
|
50 | return stringmatch(mctx, _getkindpat(x, y, matchmod.allpatternkinds, | |
51 | _("pattern must be a string"))) |
|
51 | _("pattern must be a string"))) | |
52 |
|
52 | |||
|
53 | def patternsmatch(mctx, *xs): | |||
|
54 | allkinds = matchmod.allpatternkinds | |||
|
55 | patterns = [getpattern(x, allkinds, _("pattern must be a string")) | |||
|
56 | for x in xs] | |||
|
57 | return mctx.matcher(patterns) | |||
|
58 | ||||
53 | def andmatch(mctx, x, y): |
|
59 | def andmatch(mctx, x, y): | |
54 | xm = getmatch(mctx, x) |
|
60 | xm = getmatch(mctx, x) | |
55 | ym = getmatch(mctx, y) |
|
61 | ym = getmatch(mctx, y) | |
@@ -436,6 +442,7 b' methods = {' | |||||
436 | 'string': stringmatch, |
|
442 | 'string': stringmatch, | |
437 | 'symbol': stringmatch, |
|
443 | 'symbol': stringmatch, | |
438 | 'kindpat': kindpatmatch, |
|
444 | 'kindpat': kindpatmatch, | |
|
445 | 'patterns': patternsmatch, | |||
439 | 'and': andmatch, |
|
446 | 'and': andmatch, | |
440 | 'or': ormatch, |
|
447 | 'or': ormatch, | |
441 | 'minus': minusmatch, |
|
448 | 'minus': minusmatch, |
@@ -185,6 +185,21 b' def _optimizeandops(op, ta, tb):' | |||||
185 | return ('minus', ta, tb[1]) |
|
185 | return ('minus', ta, tb[1]) | |
186 | return (op, ta, tb) |
|
186 | return (op, ta, tb) | |
187 |
|
187 | |||
|
188 | def _optimizeunion(xs): | |||
|
189 | # collect string patterns so they can be compiled into a single regexp | |||
|
190 | ws, ts, ss = [], [], [] | |||
|
191 | for x in xs: | |||
|
192 | w, t = _optimize(x) | |||
|
193 | if t is not None and t[0] in {'string', 'symbol', 'kindpat'}: | |||
|
194 | ss.append(t) | |||
|
195 | continue | |||
|
196 | ws.append(w) | |||
|
197 | ts.append(t) | |||
|
198 | if ss: | |||
|
199 | ws.append(WEIGHT_CHECK_FILENAME) | |||
|
200 | ts.append(('patterns',) + tuple(ss)) | |||
|
201 | return ws, ts | |||
|
202 | ||||
188 | def _optimize(x): |
|
203 | def _optimize(x): | |
189 | if x is None: |
|
204 | if x is None: | |
190 | return 0, x |
|
205 | return 0, x | |
@@ -206,7 +221,9 b' def _optimize(x):' | |||||
206 | else: |
|
221 | else: | |
207 | return wb, _optimizeandops(op, tb, ta) |
|
222 | return wb, _optimizeandops(op, tb, ta) | |
208 | if op == 'or': |
|
223 | if op == 'or': | |
209 |
ws, ts = |
|
224 | ws, ts = _optimizeunion(x[1:]) | |
|
225 | if len(ts) == 1: | |||
|
226 | return ws[0], ts[0] # 'or' operation is fully optimized out | |||
210 | ts = tuple(it[1] for it in sorted(enumerate(ts), |
|
227 | ts = tuple(it[1] for it in sorted(enumerate(ts), | |
211 | key=lambda it: ws[it[0]])) |
|
228 | key=lambda it: ws[it[0]])) | |
212 | return max(ws), (op,) + ts |
|
229 | return max(ws), (op,) + ts |
@@ -40,7 +40,7 b' def _compile(tree):' | |||||
40 | return f |
|
40 | return f | |
41 | raise error.ParseError(_("unsupported file pattern: %s") % name, |
|
41 | raise error.ParseError(_("unsupported file pattern: %s") % name, | |
42 | hint=_('paths must be prefixed with "path:"')) |
|
42 | hint=_('paths must be prefixed with "path:"')) | |
43 |
elif op |
|
43 | elif op in {'or', 'patterns'}: | |
44 | funcs = [_compile(x) for x in tree[1:]] |
|
44 | funcs = [_compile(x) for x in tree[1:]] | |
45 | return lambda n, s: any(f(n, s) for f in funcs) |
|
45 | return lambda n, s: any(f(n, s) for f in funcs) | |
46 | elif op == 'and': |
|
46 | elif op == 'and': |
@@ -53,9 +53,7 b' Test operators and basic patterns' | |||||
53 | (symbol 'glob') |
|
53 | (symbol 'glob') | |
54 | (symbol 'b?'))) |
|
54 | (symbol 'b?'))) | |
55 | * matcher: |
|
55 | * matcher: | |
56 | <unionmatcher matchers=[ |
|
56 | <patternmatcher patterns='(?:a1(?:/|$)|b.$)'> | |
57 | <patternmatcher patterns='(?:a1(?:/|$))'>, |
|
|||
58 | <patternmatcher patterns='(?:b.$)'>]> |
|
|||
59 | a1 |
|
57 | a1 | |
60 | b1 |
|
58 | b1 | |
61 | b2 |
|
59 | b2 | |
@@ -182,8 +180,9 b' Show parsed tree at stages:' | |||||
182 | None))) |
|
180 | None))) | |
183 | * optimized: |
|
181 | * optimized: | |
184 | (or |
|
182 | (or | |
185 | (symbol 'a1') |
|
183 | (patterns | |
186 |
(symbol 'a |
|
184 | (symbol 'a1') | |
|
185 | (symbol 'a2')) | |||
187 | (and |
|
186 | (and | |
188 | (func |
|
187 | (func | |
189 | (symbol 'clean') |
|
188 | (symbol 'clean') | |
@@ -193,8 +192,7 b' Show parsed tree at stages:' | |||||
193 | (string 'b')))) |
|
192 | (string 'b')))) | |
194 | * matcher: |
|
193 | * matcher: | |
195 | <unionmatcher matchers=[ |
|
194 | <unionmatcher matchers=[ | |
196 | <patternmatcher patterns='(?:a1$)'>, |
|
195 | <patternmatcher patterns='(?:a1$|a2$)'>, | |
197 | <patternmatcher patterns='(?:a2$)'>, |
|
|||
198 | <intersectionmatcher |
|
196 | <intersectionmatcher | |
199 | m1=<predicatenmatcher pred=clean>, |
|
197 | m1=<predicatenmatcher pred=clean>, | |
200 | m2=<predicatenmatcher pred=grep('b')>>]> |
|
198 | m2=<predicatenmatcher pred=grep('b')>>]> | |
@@ -203,13 +201,30 b' Show parsed tree at stages:' | |||||
203 | b1 |
|
201 | b1 | |
204 | b2 |
|
202 | b2 | |
205 |
|
203 | |||
|
204 | Union of basic patterns: | |||
|
205 | ||||
|
206 | $ fileset -p optimized -s -r. 'a1 or a2 or path:b1' | |||
|
207 | * optimized: | |||
|
208 | (patterns | |||
|
209 | (symbol 'a1') | |||
|
210 | (symbol 'a2') | |||
|
211 | (kindpat | |||
|
212 | (symbol 'path') | |||
|
213 | (symbol 'b1'))) | |||
|
214 | * matcher: | |||
|
215 | <patternmatcher patterns='(?:a1$|a2$|b1(?:/|$))'> | |||
|
216 | a1 | |||
|
217 | a2 | |||
|
218 | b1 | |||
|
219 | ||||
206 | OR expression should be reordered by weight: |
|
220 | OR expression should be reordered by weight: | |
207 |
|
221 | |||
208 | $ fileset -p optimized -s -r. 'grep("a") or a1 or grep("b") or b2' |
|
222 | $ fileset -p optimized -s -r. 'grep("a") or a1 or grep("b") or b2' | |
209 | * optimized: |
|
223 | * optimized: | |
210 | (or |
|
224 | (or | |
211 | (symbol 'a1') |
|
225 | (patterns | |
212 |
(symbol |
|
226 | (symbol 'a1') | |
|
227 | (symbol 'b2')) | |||
213 | (func |
|
228 | (func | |
214 | (symbol 'grep') |
|
229 | (symbol 'grep') | |
215 | (string 'a')) |
|
230 | (string 'a')) | |
@@ -218,8 +233,7 b' OR expression should be reordered by wei' | |||||
218 | (string 'b'))) |
|
233 | (string 'b'))) | |
219 | * matcher: |
|
234 | * matcher: | |
220 | <unionmatcher matchers=[ |
|
235 | <unionmatcher matchers=[ | |
221 | <patternmatcher patterns='(?:a1$)'>, |
|
236 | <patternmatcher patterns='(?:a1$|b2$)'>, | |
222 | <patternmatcher patterns='(?:b2$)'>, |
|
|||
223 | <predicatenmatcher pred=grep('a')>, |
|
237 | <predicatenmatcher pred=grep('a')>, | |
224 | <predicatenmatcher pred=grep('b')>]> |
|
238 | <predicatenmatcher pred=grep('b')>]> | |
225 | a1 |
|
239 | a1 |
General Comments 0
You need to be logged in to leave comments.
Login now