comparison mercurial/revset.py @ 29119:a032ebea4e97

revset: factor out public optimize() function from recursion New optimize() hides internal arguments and return values. This makes it easy to add more parameters and return values to _optimize().
author Yuya Nishihara <yuya@tcha.org>
date Mon, 02 May 2016 12:09:00 +0900
parents 8c295c3b2ce2
children 64c1955a0461
comparison
equal deleted inserted replaced
29118:8c295c3b2ce2 29119:a032ebea4e97
2085 and bases[0] == 'not' 2085 and bases[0] == 'not'
2086 and bases[1][0] == 'func' 2086 and bases[1][0] == 'func'
2087 and getstring(bases[1][1], _('not a symbol')) == 'ancestors'): 2087 and getstring(bases[1][1], _('not a symbol')) == 'ancestors'):
2088 return ('list', revs[2], bases[1][2]) 2088 return ('list', revs[2], bases[1][2])
2089 2089
2090 def optimize(x, small): 2090 def _optimize(x, small):
2091 if x is None: 2091 if x is None:
2092 return 0, x 2092 return 0, x
2093 2093
2094 smallbonus = 1 2094 smallbonus = 1
2095 if small: 2095 if small:
2096 smallbonus = .5 2096 smallbonus = .5
2097 2097
2098 op = x[0] 2098 op = x[0]
2099 if op == 'minus': 2099 if op == 'minus':
2100 return optimize(('and', x[1], ('not', x[2])), small) 2100 return _optimize(('and', x[1], ('not', x[2])), small)
2101 elif op == 'only': 2101 elif op == 'only':
2102 t = ('func', ('symbol', 'only'), ('list', x[1], x[2])) 2102 t = ('func', ('symbol', 'only'), ('list', x[1], x[2]))
2103 return optimize(t, small) 2103 return _optimize(t, small)
2104 elif op == 'onlypost': 2104 elif op == 'onlypost':
2105 return optimize(('func', ('symbol', 'only'), x[1]), small) 2105 return _optimize(('func', ('symbol', 'only'), x[1]), small)
2106 elif op == 'dagrangepre': 2106 elif op == 'dagrangepre':
2107 return optimize(('func', ('symbol', 'ancestors'), x[1]), small) 2107 return _optimize(('func', ('symbol', 'ancestors'), x[1]), small)
2108 elif op == 'dagrangepost': 2108 elif op == 'dagrangepost':
2109 return optimize(('func', ('symbol', 'descendants'), x[1]), small) 2109 return _optimize(('func', ('symbol', 'descendants'), x[1]), small)
2110 elif op == 'rangeall': 2110 elif op == 'rangeall':
2111 return optimize(('range', ('string', '0'), ('string', 'tip')), small) 2111 return _optimize(('range', ('string', '0'), ('string', 'tip')), small)
2112 elif op == 'rangepre': 2112 elif op == 'rangepre':
2113 return optimize(('range', ('string', '0'), x[1]), small) 2113 return _optimize(('range', ('string', '0'), x[1]), small)
2114 elif op == 'rangepost': 2114 elif op == 'rangepost':
2115 return optimize(('range', x[1], ('string', 'tip')), small) 2115 return _optimize(('range', x[1], ('string', 'tip')), small)
2116 elif op == 'negate': 2116 elif op == 'negate':
2117 s = getstring(x[1], _("can't negate that")) 2117 s = getstring(x[1], _("can't negate that"))
2118 return optimize(('string', '-' + s), small) 2118 return _optimize(('string', '-' + s), small)
2119 elif op in 'string symbol negate': 2119 elif op in 'string symbol negate':
2120 return smallbonus, x # single revisions are small 2120 return smallbonus, x # single revisions are small
2121 elif op == 'and': 2121 elif op == 'and':
2122 wa, ta = optimize(x[1], True) 2122 wa, ta = _optimize(x[1], True)
2123 wb, tb = optimize(x[2], True) 2123 wb, tb = _optimize(x[2], True)
2124 w = min(wa, wb) 2124 w = min(wa, wb)
2125 2125
2126 # (::x and not ::y)/(not ::y and ::x) have a fast path 2126 # (::x and not ::y)/(not ::y and ::x) have a fast path
2127 tm = _matchonly(ta, tb) or _matchonly(tb, ta) 2127 tm = _matchonly(ta, tb) or _matchonly(tb, ta)
2128 if tm: 2128 if tm:
2144 if len(ss) == 1: 2144 if len(ss) == 1:
2145 w, t = ss[0] 2145 w, t = ss[0]
2146 else: 2146 else:
2147 s = '\0'.join(t[1] for w, t in ss) 2147 s = '\0'.join(t[1] for w, t in ss)
2148 y = ('func', ('symbol', '_list'), ('string', s)) 2148 y = ('func', ('symbol', '_list'), ('string', s))
2149 w, t = optimize(y, False) 2149 w, t = _optimize(y, False)
2150 ws.append(w) 2150 ws.append(w)
2151 ts.append(t) 2151 ts.append(t)
2152 del ss[:] 2152 del ss[:]
2153 for y in x[1:]: 2153 for y in x[1:]:
2154 w, t = optimize(y, False) 2154 w, t = _optimize(y, False)
2155 if t is not None and (t[0] == 'string' or t[0] == 'symbol'): 2155 if t is not None and (t[0] == 'string' or t[0] == 'symbol'):
2156 ss.append((w, t)) 2156 ss.append((w, t))
2157 continue 2157 continue
2158 flushss() 2158 flushss()
2159 ws.append(w) 2159 ws.append(w)
2167 return max(ws), (op,) + tuple(ts) 2167 return max(ws), (op,) + tuple(ts)
2168 elif op == 'not': 2168 elif op == 'not':
2169 # Optimize not public() to _notpublic() because we have a fast version 2169 # Optimize not public() to _notpublic() because we have a fast version
2170 if x[1] == ('func', ('symbol', 'public'), None): 2170 if x[1] == ('func', ('symbol', 'public'), None):
2171 newsym = ('func', ('symbol', '_notpublic'), None) 2171 newsym = ('func', ('symbol', '_notpublic'), None)
2172 o = optimize(newsym, not small) 2172 o = _optimize(newsym, not small)
2173 return o[0], o[1] 2173 return o[0], o[1]
2174 else: 2174 else:
2175 o = optimize(x[1], not small) 2175 o = _optimize(x[1], not small)
2176 return o[0], (op, o[1]) 2176 return o[0], (op, o[1])
2177 elif op == 'parentpost': 2177 elif op == 'parentpost':
2178 o = optimize(x[1], small) 2178 o = _optimize(x[1], small)
2179 return o[0], (op, o[1]) 2179 return o[0], (op, o[1])
2180 elif op == 'group': 2180 elif op == 'group':
2181 return optimize(x[1], small) 2181 return _optimize(x[1], small)
2182 elif op in 'dagrange range parent ancestorspec': 2182 elif op in 'dagrange range parent ancestorspec':
2183 if op == 'parent': 2183 if op == 'parent':
2184 # x^:y means (x^) : y, not x ^ (:y) 2184 # x^:y means (x^) : y, not x ^ (:y)
2185 post = ('parentpost', x[1]) 2185 post = ('parentpost', x[1])
2186 if x[2][0] == 'dagrangepre': 2186 if x[2][0] == 'dagrangepre':
2187 return optimize(('dagrange', post, x[2][1]), small) 2187 return _optimize(('dagrange', post, x[2][1]), small)
2188 elif x[2][0] == 'rangepre': 2188 elif x[2][0] == 'rangepre':
2189 return optimize(('range', post, x[2][1]), small) 2189 return _optimize(('range', post, x[2][1]), small)
2190 2190
2191 wa, ta = optimize(x[1], small) 2191 wa, ta = _optimize(x[1], small)
2192 wb, tb = optimize(x[2], small) 2192 wb, tb = _optimize(x[2], small)
2193 return wa + wb, (op, ta, tb) 2193 return wa + wb, (op, ta, tb)
2194 elif op == 'list': 2194 elif op == 'list':
2195 ws, ts = zip(*(optimize(y, small) for y in x[1:])) 2195 ws, ts = zip(*(_optimize(y, small) for y in x[1:]))
2196 return sum(ws), (op,) + ts 2196 return sum(ws), (op,) + ts
2197 elif op == 'func': 2197 elif op == 'func':
2198 f = getstring(x[1], _("not a symbol")) 2198 f = getstring(x[1], _("not a symbol"))
2199 wa, ta = optimize(x[2], small) 2199 wa, ta = _optimize(x[2], small)
2200 if f in ("author branch closed date desc file grep keyword " 2200 if f in ("author branch closed date desc file grep keyword "
2201 "outgoing user"): 2201 "outgoing user"):
2202 w = 10 # slow 2202 w = 10 # slow
2203 elif f in "modifies adds removes": 2203 elif f in "modifies adds removes":
2204 w = 30 # slower 2204 w = 30 # slower
2213 else: 2213 else:
2214 w = 1 2214 w = 1
2215 return w + wa, (op, x[1], ta) 2215 return w + wa, (op, x[1], ta)
2216 return 1, x 2216 return 1, x
2217 2217
2218 def optimize(tree):
2219 _weight, newtree = _optimize(tree, small=True)
2220 return newtree
2221
2218 # the set of valid characters for the initial letter of symbols in 2222 # the set of valid characters for the initial letter of symbols in
2219 # alias declarations and definitions 2223 # alias declarations and definitions
2220 _aliassyminitletters = set(c for c in [chr(i) for i in xrange(256)] 2224 _aliassyminitletters = set(c for c in [chr(i) for i in xrange(256)]
2221 if c.isalnum() or c in '._@$' or ord(c) > 127) 2225 if c.isalnum() or c in '._@$' or ord(c) > 127)
2222 2226
2328 2332
2329 def _makematcher(ui, tree, repo): 2333 def _makematcher(ui, tree, repo):
2330 if ui: 2334 if ui:
2331 tree = expandaliases(ui, tree, showwarning=ui.warn) 2335 tree = expandaliases(ui, tree, showwarning=ui.warn)
2332 tree = foldconcat(tree) 2336 tree = foldconcat(tree)
2333 weight, tree = optimize(tree, True) 2337 tree = optimize(tree)
2334 posttreebuilthook(tree, repo) 2338 posttreebuilthook(tree, repo)
2335 def mfunc(repo, subset=None): 2339 def mfunc(repo, subset=None):
2336 if subset is None: 2340 if subset is None:
2337 subset = fullreposet(repo) 2341 subset = fullreposet(repo)
2338 if util.safehasattr(subset, 'isascending'): 2342 if util.safehasattr(subset, 'isascending'):