##// END OF EJS Templates
fileset: combine union of basic patterns into single matcher...
Yuya Nishihara -
r38901:899b4c74 default
parent child Browse files
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 = zip(*(_optimize(y) for y in x[1:]))
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 == 'or':
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 'a2')
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 'b2')
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