[PATCH 03 of 17 RFC] clfilter: make the revlog class responsible of all its iteration

pierre-yves.david at logilab.fr pierre-yves.david at logilab.fr
Mon Sep 3 07:58:27 CDT 2012


# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at logilab.fr>
# Date 1346674094 -7200
# Node ID 8f7f95dfb308fd81d98cb95626e6fa1c4bd9b44c
# Parent  123b6a0821ac10dfe7029f2952e631eac14a5a4b
clfilter: make the revlog class responsible of all its iteration

This prepares changelog level filtering. We need the algorithms used in revlog to
work on a subset of revisions.  To achieve this, the use of explicit range of
revision is banned. `range` and `xrange` calls are replaced by a `revlog.irevs`
method. Filtered super class can then overwrite the `irevs` method to filter out
revision.

diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -254,10 +254,17 @@ class revlog(object):
     def __len__(self):
         return len(self.index) - 1
     def __iter__(self):
         for i in xrange(len(self)):
             yield i
+    def irevs(self, start=0, stop=None):
+        """iterate over all rev in this revlog (from start to stop)"""
+        if stop is None:
+            stop = len(self)
+        else:
+            stop += 1
+        return xrange(start, stop)
 
     @util.propertycache
     def nodemap(self):
         self.rev(self.node(0))
         return self._nodecache
@@ -372,11 +379,11 @@ class revlog(object):
             for i in self:
                 yield i
             return
 
         seen = set(revs)
-        for i in xrange(first + 1, len(self)):
+        for i in self.irevs(start=first + 1):
             for x in self.parentrevs(i):
                 if x != nullrev and x in seen:
                     seen.add(i)
                     yield i
                     break
@@ -547,11 +554,11 @@ class revlog(object):
         # Our topologically sorted list of output nodes.
         orderedout = []
         # Don't start at nullid since we don't want nullid in our output list,
         # and if nullid shows up in descendants, empty parents will look like
         # they're descendants.
-        for r in xrange(max(lowestrev, 0), highestrev + 1):
+        for r in self.irevs(start=max(lowestrev, 0), stop=highestrev + 1):
             n = self.node(r)
             isdescendant = False
             if lowestrev == nullrev:  # Everybody is a descendant of nullid
                 isdescendant = True
             elif n in descendants:
@@ -604,11 +611,11 @@ class revlog(object):
         count = len(self)
         if not count:
             return [nullrev]
         ishead = [1] * (count + 1)
         index = self.index
-        for r in xrange(count):
+        for r in self:
             e = index[r]
             ishead[e[5]] = ishead[e[6]] = 0
         return [r for r in xrange(count) if ishead[r]]
 
     def heads(self, start=None, stop=None):
@@ -632,11 +639,11 @@ class revlog(object):
         startrev = self.rev(start)
         reachable = set((startrev,))
         heads = set((startrev,))
 
         parentrevs = self.parentrevs
-        for r in xrange(startrev + 1, len(self)):
+        for r in self.irevs(start=startrev + 1):
             for p in parentrevs(r):
                 if p in reachable:
                     if r not in stoprevs:
                         reachable.add(r)
                     heads.add(r)
@@ -647,11 +654,11 @@ class revlog(object):
 
     def children(self, node):
         """find the children of a given node"""
         c = []
         p = self.rev(node)
-        for r in range(p + 1, len(self)):
+        for r in self.irevs(start=p + 1):
             prevs = [pr for pr in self.parentrevs(r) if pr != nullrev]
             if prevs:
                 for pr in prevs:
                     if pr == p:
                         c.append(self.node(r))


More information about the Mercurial-devel mailing list