comparison mercurial/dagop.py @ 35296:2cb05e6043be

dagop: add smartset interface to filectxancestors() The original filectx API is kept public since we'll need it to walk ancestor (rev, match) pairs efficiently. The current implementation scans ancestors twice for 'hg log -fp FILE'.
author Yuya Nishihara <yuya@tcha.org>
date Sun, 22 Oct 2017 18:57:42 +0900
parents 205c3c6c1a51
children c9144396099b
comparison
equal deleted inserted replaced
35295:bea46aed1e1b 35296:2cb05e6043be
75 if prev != node.nullrev: 75 if prev != node.nullrev:
76 heapq.heappush(pendingheap, (heapsign * prev, pdepth)) 76 heapq.heappush(pendingheap, (heapsign * prev, pdepth))
77 77
78 def filectxancestors(fctxs, followfirst=False): 78 def filectxancestors(fctxs, followfirst=False):
79 """Like filectx.ancestors(), but can walk from multiple files/revisions, 79 """Like filectx.ancestors(), but can walk from multiple files/revisions,
80 and includes the given fctxs themselves""" 80 and includes the given fctxs themselves
81
82 Yields (rev, {fctx, ...}) pairs in descending order.
83 """
81 visit = {} 84 visit = {}
82 def addvisit(fctx): 85 def addvisit(fctx):
83 rev = fctx.rev() 86 rev = fctx.rev()
84 if rev not in visit: 87 if rev not in visit:
85 visit[rev] = set() 88 visit[rev] = set()
91 cut = None 94 cut = None
92 95
93 for c in fctxs: 96 for c in fctxs:
94 addvisit(c) 97 addvisit(c)
95 while visit: 98 while visit:
96 rev = max(visit) 99 currev = max(visit)
97 c = visit[rev].pop() 100 curfctxs = visit.pop(currev)
98 if not visit[rev]: 101 yield currev, curfctxs
99 del visit[rev] 102 for c in curfctxs:
100 yield c 103 for parent in c.parents()[:cut]:
101 for parent in c.parents()[:cut]: 104 addvisit(parent)
102 addvisit(parent) 105
106 def filerevancestors(fctxs, followfirst=False):
107 """Like filectx.ancestors(), but can walk from multiple files/revisions,
108 and includes the given fctxs themselves
109
110 Returns a smartset.
111 """
112 gen = (rev for rev, _cs in filectxancestors(fctxs, followfirst))
113 return generatorset(gen, iterasc=False)
103 114
104 def _genrevancestors(repo, revs, followfirst, startdepth, stopdepth, cutfunc): 115 def _genrevancestors(repo, revs, followfirst, startdepth, stopdepth, cutfunc):
105 if followfirst: 116 if followfirst:
106 cut = 1 117 cut = 1
107 else: 118 else: