# HG changeset patch # User Pierre-Yves David # Date 1428096953 25200 # Node ID f76595f6ed7c5147cbaf8ab823b5636d66476de3 # Parent 72d34c5a66141361ce7eb0d92d7e2315c21c9b2f repoview: simplify process in _getstatichidden Since all children are processed before their parents, we can apply the following algorithm: For each rev (descending order): * If I'm still hidden, no children will block me, * If I'm not hidden, I must remove my parent from the hidden set, This allows us to dynamically change the set of 'hidden' revisions, dropping the need for the 'actuallyhidden' dictionary and the 'blocked' boolean in the queue. As before, we start iterating from all heads and stop at the first public changesets. This ensures the hidden computation is 'O(not public())' instead of 'O(len(min(not public()):))'. diff -r 72d34c5a6614 -r f76595f6ed7c mercurial/repoview.py --- a/mercurial/repoview.py Fri Apr 03 14:16:50 2015 -0700 +++ b/mercurial/repoview.py Fri Apr 03 14:35:53 2015 -0700 @@ -34,35 +34,30 @@ """ assert not repo.changelog.filteredrevs - hideable = hideablerevs(repo) - if hideable: - actuallyhidden = {} + hidden = set(hideablerevs(repo)) + if hidden: getphase = repo._phasecache.phase getparentrevs = repo.changelog.parentrevs - heap = [(-r, False) for r in repo.changelog.headrevs()] + heap = [-r for r in repo.changelog.headrevs()] heapq.heapify(heap) heappop = heapq.heappop heappush = heapq.heappush while heap: - rev, blocked = heappop(heap) - rev = - rev - phase = getphase(repo, rev) - # Skip nodes which are public (guaranteed to not be hidden) and - # nodes which have already been processed and won't be blocked by - # the previous node. - if phase == 0 or (not blocked and rev in actuallyhidden): + rev = -heappop(heap) + # Skip nodes which are public (guaranteed to not be hidden) + if not getphase(repo, rev): continue - if rev in hideable: - if blocked: - actuallyhidden[rev] = False - else: - actuallyhidden.setdefault(rev, True) - else: - blocked = True - - for parent in (p for p in getparentrevs(rev) if p != nullrev): - heappush(heap, (- parent, blocked)) - return set(rev for rev, hidden in actuallyhidden.iteritems() if hidden) + # All children have been processed so at that point, if no children + # removed 'rev' from the 'hidden' set, 'rev' is going to be hidden. + blocker = rev not in hidden + for parent in getparentrevs(rev): + if parent == nullrev: + continue + if blocker: + # If visible, ensure parent will be visible too + hidden.discard(parent) + heappush(heap, -parent) + return hidden def _getdynamicblockers(repo): """Non-cacheable revisions blocking hidden changesets from being filtered.