Mercurial > hg
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 |