comparison mercurial/ancestor.py @ 18090:9abc55ef85b5

revlog: move ancestor generation out to a new class This refactoring is to prepare for implementing lazy membership.
author Siddharth Agarwal <sid0@fb.com>
date Tue, 18 Dec 2012 10:14:01 -0800
parents b3ba69692f8a
children f7f8159caad3
comparison
equal deleted inserted replaced
18089:0127366df8fe 18090:9abc55ef85b5
3 # Copyright 2006 Matt Mackall <mpm@selenic.com> 3 # Copyright 2006 Matt Mackall <mpm@selenic.com>
4 # 4 #
5 # This software may be used and distributed according to the terms of the 5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version. 6 # GNU General Public License version 2 or any later version.
7 7
8 import heapq 8 import heapq, util
9 from node import nullrev 9 from node import nullrev
10 10
11 def ancestor(a, b, pfunc): 11 def ancestor(a, b, pfunc):
12 """ 12 """
13 Returns the common ancestor of a and b that is furthest from a 13 Returns the common ancestor of a and b that is furthest from a
169 # visit later 169 # visit later
170 thisvisit.add(p) 170 thisvisit.add(p)
171 171
172 missing.reverse() 172 missing.reverse()
173 return missing 173 return missing
174
175 class lazyancestors(object):
176 def __init__(self, cl, revs, stoprev=0, inclusive=False):
177 """Create a new object generating ancestors for the given revs. Does
178 not generate revs lower than stoprev.
179
180 This is computed lazily starting from revs. The object only supports
181 iteration.
182
183 cl should be a changelog and revs should be an iterable. inclusive is
184 a boolean that indicates whether revs should be included. Revs lower
185 than stoprev will not be generated.
186
187 Result does not include the null revision."""
188 self._parentrevs = cl.parentrevs
189 self._initrevs = revs
190 self._stoprev = stoprev
191 self._inclusive = inclusive
192
193 def __iter__(self):
194 """Generate the ancestors of _initrevs in reverse topological order.
195
196 If inclusive is False, yield a sequence of revision numbers starting
197 with the parents of each revision in revs, i.e., each revision is *not*
198 considered an ancestor of itself. Results are in breadth-first order:
199 parents of each rev in revs, then parents of those, etc.
200
201 If inclusive is True, yield all the revs first (ignoring stoprev),
202 then yield all the ancestors of revs as when inclusive is False.
203 If an element in revs is an ancestor of a different rev it is not
204 yielded again."""
205 seen = set()
206 revs = self._initrevs
207 if self._inclusive:
208 for rev in revs:
209 yield rev
210 seen.update(revs)
211
212 parentrevs = self._parentrevs
213 stoprev = self._stoprev
214 visit = util.deque(revs)
215
216 while visit:
217 for parent in parentrevs(visit.popleft()):
218 if parent >= stoprev and parent not in seen:
219 visit.append(parent)
220 seen.add(parent)
221 yield parent