[PATCH 1 of 4 V3 part 2] revlog: move ancestor generation out to a new class
Siddharth Agarwal
sid0 at fb.com
Mon Dec 17 23:30:10 CST 2012
# HG changeset patch
# User Siddharth Agarwal <sid0 at fb.com>
# Date 1355805744 28800
# Node ID 492535c0a3b45125888c7d20d402857cecaeae00
# Parent aca213182e8fffe65fecff0af0b373f4c0a3cdfc
revlog: move ancestor generation out to a new class
This refactoring is to prepare for implementing lazy membership.
diff -r aca213182e8f -r 492535c0a3b4 mercurial/ancestor.py
--- a/mercurial/ancestor.py Mon Dec 17 15:08:37 2012 -0800
+++ b/mercurial/ancestor.py Mon Dec 17 20:42:24 2012 -0800
@@ -5,7 +5,7 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-import error, heapq
+import error, heapq, util
from node import nullrev
def ancestors(pfunc, *orignodes):
@@ -316,3 +316,53 @@
missing.reverse()
return missing
+
+class lazyancestors(object):
+ def __init__(self, cl, revs, stoprev=0, inclusive=False):
+ """Create a new object generating ancestors for the given revs. Does
+ not generate revs lower than stoprev.
+
+ This is computed lazily starting from revs. The object only supports
+ iteration.
+
+ cl should be a changelog and revs should be an iterable. inclusive is
+ a boolean that indicates whether revs should be included. Revs lower
+ than stoprev will not be generated.
+
+ Result does not include the null revision."""
+ self._parentrevs = cl.parentrevs
+ self._initrevs = revs
+ self._stoprev = stoprev
+ self._inclusive = inclusive
+
+ def __iter__(self):
+ """Generate the ancestors of _initrevs in reverse topological order.
+
+ If inclusive is False, yield a sequence of revision numbers starting
+ with the parents of each revision in revs, i.e., each revision is *not*
+ considered an ancestor of itself. Results are in breadth-first order:
+ parents of each rev in revs, then parents of those, etc.
+
+ If inclusive is True, yield all the revs first (ignoring stoprev),
+ then yield all the ancestors of revs as when inclusive is False.
+ If an element in revs is an ancestor of a different rev it is not
+ yielded again."""
+ seen = set([nullrev])
+ if self._inclusive:
+ for rev in revs:
+ yield rev
+ seen.update(revs)
+
+ parentrevs = self._parentrevs
+ revs = self._initrevs
+ stoprev = self._stoprev
+ visit = util.deque(revs)
+
+ while visit:
+ for parent in parentrevs(visit.popleft()):
+ if parent < stoprev:
+ continue
+ if parent not in seen:
+ visit.append(parent)
+ seen.add(parent)
+ yield parent
diff -r aca213182e8f -r 492535c0a3b4 mercurial/revlog.py
--- a/mercurial/revlog.py Mon Dec 17 15:08:37 2012 -0800
+++ b/mercurial/revlog.py Mon Dec 17 20:42:24 2012 -0800
@@ -345,31 +345,10 @@
"""Generate the ancestors of 'revs' in reverse topological order.
Does not generate revs lower than stoprev.
- If inclusive is False, yield a sequence of revision numbers starting
- with the parents of each revision in revs, i.e., each revision is *not*
- considered an ancestor of itself. Results are in breadth-first order:
- parents of each rev in revs, then parents of those, etc.
+ See the documentation for ancestor.lazyancestors for more details."""
- If inclusive is True, yield all the revs first (ignoring stoprev),
- then yield all the ancestors of revs as when inclusive is False.
- If an element in revs is an ancestor of a different rev it is not
- yielded again.
-
- Result does not include the null revision."""
- visit = util.deque(revs)
- seen = set([nullrev])
- if inclusive:
- for rev in revs:
- yield rev
- seen.update(revs)
- while visit:
- for parent in self.parentrevs(visit.popleft()):
- if parent < stoprev:
- continue
- if parent not in seen:
- visit.append(parent)
- seen.add(parent)
- yield parent
+ return ancestor.lazyancestors(self, revs, stoprev=stoprev,
+ inclusive=inclusive)
def descendants(self, revs):
"""Generate the descendants of 'revs' in revision order.
More information about the Mercurial-devel
mailing list