390 elif op == b'dagrangepost': |
390 elif op == b'dagrangepost': |
391 return _analyze(_build(b'descendants(_)', x[1])) |
391 return _analyze(_build(b'descendants(_)', x[1])) |
392 elif op == b'negate': |
392 elif op == b'negate': |
393 s = getstring(x[1], _(b"can't negate that")) |
393 s = getstring(x[1], _(b"can't negate that")) |
394 return _analyze((b'string', b'-' + s)) |
394 return _analyze((b'string', b'-' + s)) |
395 elif op in (b'string', b'symbol', b'smartset'): |
395 elif op in (b'string', b'symbol', b'smartset', b'nodeset'): |
396 return x |
396 return x |
397 elif op == b'rangeall': |
397 elif op == b'rangeall': |
398 return (op, None) |
398 return (op, None) |
399 elif op in {b'or', b'not', b'rangepre', b'rangepost', b'parentpost'}: |
399 elif op in {b'or', b'not', b'rangepre', b'rangepost', b'parentpost'}: |
400 return (op, _analyze(x[1])) |
400 return (op, _analyze(x[1])) |
439 def _optimize(x): |
439 def _optimize(x): |
440 if x is None: |
440 if x is None: |
441 return 0, x |
441 return 0, x |
442 |
442 |
443 op = x[0] |
443 op = x[0] |
444 if op in (b'string', b'symbol', b'smartset'): |
444 if op in (b'string', b'symbol', b'smartset', b'nodeset'): |
445 return 0.5, x # single revisions are small |
445 # single revisions are small, and set of already computed revision are assumed to be cheap. |
|
446 return 0.5, x |
446 elif op == b'and': |
447 elif op == b'and': |
447 wa, ta = _optimize(x[1]) |
448 wa, ta = _optimize(x[1]) |
448 wb, tb = _optimize(x[2]) |
449 wb, tb = _optimize(x[2]) |
449 w = min(wa, wb) |
450 w = min(wa, wb) |
450 |
451 |
782 ret.append(arg) |
783 ret.append(arg) |
783 elif t == b'baseset': |
784 elif t == b'baseset': |
784 if isinstance(arg, set): |
785 if isinstance(arg, set): |
785 arg = sorted(arg) |
786 arg = sorted(arg) |
786 ret.append(_formatintlist(list(arg))) |
787 ret.append(_formatintlist(list(arg))) |
|
788 elif t == b'nodeset': |
|
789 ret.append(_formatlistexp(list(arg), b"n")) |
787 else: |
790 else: |
788 raise error.ProgrammingError(b"unknown revspec item type: %r" % t) |
791 raise error.ProgrammingError(b"unknown revspec item type: %r" % t) |
789 return b''.join(ret) |
792 return b''.join(ret) |
790 |
793 |
791 |
794 |
797 for t, arg in parsed: |
800 for t, arg in parsed: |
798 if t is None: |
801 if t is None: |
799 ret.append(arg) |
802 ret.append(arg) |
800 elif t == b'baseset': |
803 elif t == b'baseset': |
801 newtree = (b'smartset', smartset.baseset(arg)) |
804 newtree = (b'smartset', smartset.baseset(arg)) |
|
805 inputs.append(newtree) |
|
806 ret.append(b"$") |
|
807 elif t == b'nodeset': |
|
808 newtree = (b'nodeset', arg) |
802 inputs.append(newtree) |
809 inputs.append(newtree) |
803 ret.append(b"$") |
810 ret.append(b"$") |
804 else: |
811 else: |
805 raise error.ProgrammingError(b"unknown revspec item type: %r" % t) |
812 raise error.ProgrammingError(b"unknown revspec item type: %r" % t) |
806 expr = b''.join(ret) |
813 expr = b''.join(ret) |
861 # extra cost. If we are going to serialize it we better |
868 # extra cost. If we are going to serialize it we better |
862 # skip it. |
869 # skip it. |
863 ret.append((b'baseset', arg)) |
870 ret.append((b'baseset', arg)) |
864 pos += 1 |
871 pos += 1 |
865 continue |
872 continue |
|
873 elif islist and d == b'n' and arg: |
|
874 # we cannot turn the node into revision yet, but not |
|
875 # serializing them will same a lot of time for large set. |
|
876 ret.append((b'nodeset', arg)) |
|
877 pos += 1 |
|
878 continue |
866 try: |
879 try: |
867 ret.append((None, f(list(arg), d))) |
880 ret.append((None, f(list(arg), d))) |
868 except (TypeError, ValueError): |
881 except (TypeError, ValueError): |
869 raise error.ParseError(_(b'invalid argument for revspec')) |
882 raise error.ParseError(_(b'invalid argument for revspec')) |
870 else: |
883 else: |