comparison mercurial/revset.py @ 31037:17b5cda5a84a

revset: use phasecache.getrevset This is part of a refactoring that moves some phase query optimization from revset.py to phases.py. See the previous patch for motivation. This patch changes revset code to use phasecache.getrevset so it no longer accesses the private field: _phasecache._phasesets directly. For performance impact, this patch was tested using the following query, on my hg-committed repo: for i in 'public()' 'not public()' 'draft()' 'not draft()'; do echo $i; hg perfrevset "$i"; hg perfrevset "$i" --hidden; done For the CPython implementation, most operations are unchanged (within +/- 1%), while "not public()" and "draft()" is noticeably faster on an unfiltered repo. It may be because the new code avoids a set copy if filteredrevs is empty. revset | public() | not public() | draft() | not draft() hidden | yes | no | yes | no | yes | no | yes | no ------------------------------------------------------------------ before | 19006 | 17352 | 239 | 286 | 180 | 228 | 7690 | 5745 after | 19137 | 17231 | 240 | 207 | 182 | 150 | 7687 | 5658 delta | | -38% | | -52% | (timed in microseconds) For the pure Python implementation, some operations are faster while "not draft()" is noticeably slower: revset | public() | not public() | draft() | not draft() hidden | yes | no | yes | no | yes | no | yes | no ------------------------------------------------------------------------ before | 18852 | 17183 | 17758 | 15921 | 17505 | 15973 | 41521 | 39822 after | 18924 | 17380 | 17558 | 14545 | 16727 | 13593 | 48356 | 43992 delta | | -9% | -5% | -15% | +16% | +10% That may be the different performance characters of generatorset vs. filteredset. The "not draft()" query could be optimized in this case where both "public" and "secret" are passed to "getrevsets" so it won't iterate the whole repo twice.
author Jun Wu <quark@fb.com>
date Sat, 18 Feb 2017 00:39:31 -0800
parents 11c253997b0e
children 0b8356705de6
comparison
equal deleted inserted replaced
31036:bf81d3b7b2ba 31037:17b5cda5a84a
1642 else: 1642 else:
1643 up(parentrevs(r)) 1643 up(parentrevs(r))
1644 ps -= set([node.nullrev]) 1644 ps -= set([node.nullrev])
1645 return subset & ps 1645 return subset & ps
1646 1646
1647 def _phase(repo, subset, target): 1647 def _phase(repo, subset, *targets):
1648 """helper to select all rev in phase <target>""" 1648 """helper to select all rev in <targets> phases"""
1649 repo._phasecache.loadphaserevs(repo) # ensure phase's sets are loaded 1649 s = repo._phasecache.getrevset(repo, targets)
1650 if repo._phasecache._phasesets: 1650 return subset & s
1651 s = repo._phasecache._phasesets[target] - repo.changelog.filteredrevs
1652 s = baseset(s)
1653 s.sort() # set are non ordered, so we enforce ascending
1654 return subset & s
1655 else:
1656 phase = repo._phasecache.phase
1657 condition = lambda r: phase(repo, r) == target
1658 return subset.filter(condition, condrepr=('<phase %r>', target),
1659 cache=False)
1660 1651
1661 @predicate('draft()', safe=True) 1652 @predicate('draft()', safe=True)
1662 def draft(repo, subset, x): 1653 def draft(repo, subset, x):
1663 """Changeset in draft phase.""" 1654 """Changeset in draft phase."""
1664 # i18n: "draft" is a keyword 1655 # i18n: "draft" is a keyword
1715 1706
1716 # for internal use 1707 # for internal use
1717 @predicate('_notpublic', safe=True) 1708 @predicate('_notpublic', safe=True)
1718 def _notpublic(repo, subset, x): 1709 def _notpublic(repo, subset, x):
1719 getargs(x, 0, 0, "_notpublic takes no arguments") 1710 getargs(x, 0, 0, "_notpublic takes no arguments")
1720 repo._phasecache.loadphaserevs(repo) # ensure phase's sets are loaded 1711 return _phase(repo, subset, phases.draft, phases.secret)
1721 if repo._phasecache._phasesets:
1722 s = set()
1723 for u in repo._phasecache._phasesets[1:]:
1724 s.update(u)
1725 s = baseset(s - repo.changelog.filteredrevs)
1726 s.sort()
1727 return subset & s
1728 else:
1729 phase = repo._phasecache.phase
1730 target = phases.public
1731 condition = lambda r: phase(repo, r) != target
1732 return subset.filter(condition, condrepr=('<phase %r>', target),
1733 cache=False)
1734 1712
1735 @predicate('public()', safe=True) 1713 @predicate('public()', safe=True)
1736 def public(repo, subset, x): 1714 def public(repo, subset, x):
1737 """Changeset in public phase.""" 1715 """Changeset in public phase."""
1738 # i18n: "public" is a keyword 1716 # i18n: "public" is a keyword