[PATCH 1 of 3] revset: extract tree transformation from optimize()
Yuya Nishihara
yuya at tcha.org
Wed Sep 7 14:44:15 UTC 2016
# HG changeset patch
# User Yuya Nishihara <yuya at tcha.org>
# Date 1470548103 -32400
# Sun Aug 07 14:35:03 2016 +0900
# Node ID 2577e0fe3de10b2021445872fb318b6b2a28d596
# Parent c68c8b3d8c371083eedc2c0ea11e736540146421
revset: extract tree transformation from optimize()
This patch separates the simple tree transformation from the optimization step,
which is called as _analyze() since I'll extend this function to infer ordering
flags. I want to avoid making _optimize() more complicated.
This will also allow us to evaluate unoptimized tree.
diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -2342,7 +2342,68 @@ def _fixops(x):
return (op,) + tuple(_fixops(y) for y in x[1:])
+def _analyze(x):
+ """Transform raw parsed tree to evaluatable tree which can be fed to
+ optimize() or getset()
+
+ All pseudo operations should be mapped to real operations or functions
+ defined in methods or symbols table respectively.
+ """
+ if x is None:
+ return x
+
+ op = x[0]
+ if op == 'minus':
+ return _analyze(('and', x[1], ('not', x[2])))
+ elif op == 'only':
+ t = ('func', ('symbol', 'only'), ('list', x[1], x[2]))
+ return _analyze(t)
+ elif op == 'onlypost':
+ return _analyze(('func', ('symbol', 'only'), x[1]))
+ elif op == 'dagrangepre':
+ return _analyze(('func', ('symbol', 'ancestors'), x[1]))
+ elif op == 'dagrangepost':
+ return _analyze(('func', ('symbol', 'descendants'), x[1]))
+ elif op == 'rangeall':
+ return _analyze(('range', ('string', '0'), ('string', 'tip')))
+ elif op == 'rangepre':
+ return _analyze(('range', ('string', '0'), x[1]))
+ elif op == 'rangepost':
+ return _analyze(('range', x[1], ('string', 'tip')))
+ elif op == 'negate':
+ s = getstring(x[1], _("can't negate that"))
+ return _analyze(('string', '-' + s))
+ elif op in ('string', 'symbol'):
+ return x
+ elif op == 'and':
+ ta = _analyze(x[1])
+ tb = _analyze(x[2])
+ return (op, ta, tb)
+ elif op == 'or':
+ return (op,) + tuple(_analyze(y) for y in x[1:])
+ elif op == 'not':
+ return (op, _analyze(x[1]))
+ elif op == 'parentpost':
+ return (op, _analyze(x[1]))
+ elif op == 'group':
+ return _analyze(x[1])
+ elif op in ('dagrange', 'range', 'parent', 'ancestor'):
+ ta = _analyze(x[1])
+ tb = _analyze(x[2])
+ return (op, ta, tb)
+ elif op == 'list':
+ return (op,) + tuple(_analyze(y) for y in x[1:])
+ elif op == 'keyvalue':
+ return (op, x[1], _analyze(x[2]))
+ elif op == 'func':
+ return (op, x[1], _analyze(x[2]))
+ raise ValueError('invalid operator %r' % op)
+
def _optimize(x, small):
+ """Optimize evaluatable tree
+
+ All pseudo operations should be transformed beforehand.
+ """
if x is None:
return 0, x
@@ -2351,27 +2412,7 @@ def _optimize(x, small):
smallbonus = .5
op = x[0]
- if op == 'minus':
- return _optimize(('and', x[1], ('not', x[2])), small)
- elif op == 'only':
- t = ('func', ('symbol', 'only'), ('list', x[1], x[2]))
- return _optimize(t, small)
- elif op == 'onlypost':
- return _optimize(('func', ('symbol', 'only'), x[1]), small)
- elif op == 'dagrangepre':
- return _optimize(('func', ('symbol', 'ancestors'), x[1]), small)
- elif op == 'dagrangepost':
- return _optimize(('func', ('symbol', 'descendants'), x[1]), small)
- elif op == 'rangeall':
- return _optimize(('range', ('string', '0'), ('string', 'tip')), small)
- elif op == 'rangepre':
- return _optimize(('range', ('string', '0'), x[1]), small)
- elif op == 'rangepost':
- return _optimize(('range', x[1], ('string', 'tip')), small)
- elif op == 'negate':
- s = getstring(x[1], _("can't negate that"))
- return _optimize(('string', '-' + s), small)
- elif op in ('string', 'symbol'):
+ if op in ('string', 'symbol'):
return smallbonus, x # single revisions are small
elif op == 'and':
wa, ta = _optimize(x[1], True)
@@ -2432,8 +2473,6 @@ def _optimize(x, small):
elif op == 'parentpost':
o = _optimize(x[1], small)
return o[0], (op, o[1])
- elif op == 'group':
- return _optimize(x[1], small)
elif op in ('dagrange', 'range', 'parent', 'ancestor'):
wa, ta = _optimize(x[1], small)
wb, tb = _optimize(x[2], small)
@@ -2466,6 +2505,7 @@ def _optimize(x, small):
raise ValueError('invalid operator %r' % op)
def optimize(tree):
+ tree = _analyze(tree)
_weight, newtree = _optimize(tree, small=True)
return newtree
More information about the Mercurial-devel
mailing list