D4517: lazyancestors: extract __iter__ to free function

martinvonz (Martin von Zweigbergk) phabricator at mercurial-scm.org
Mon Sep 10 07:06:57 UTC 2018


martinvonz created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  The next patch will keep a reference to the returned iterator in a
  field, which would otherwise result in a reference cycle.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D4517

AFFECTED FILES
  mercurial/ancestor.py

CHANGE DETAILS

diff --git a/mercurial/ancestor.py b/mercurial/ancestor.py
--- a/mercurial/ancestor.py
+++ b/mercurial/ancestor.py
@@ -259,6 +259,37 @@
         missing.reverse()
         return missing
 
+# Extracted from lazyancestors.__iter__ to avoid a reference cycle
+def _lazyancestorsiter(parentrevs, initrevs, stoprev, inclusive):
+    seen = {nullrev}
+    revs = initrevs
+
+    schedule = heapq.heappush
+    nextitem = heapq.heappop
+    see = seen.add
+
+    if inclusive:
+        visit = [-r for r in revs]
+        seen.update(revs)
+        heapq.heapify(visit)
+    else:
+        visit = []
+        heapq.heapify(visit)
+        for r in revs:
+            for parent in parentrevs(r):
+                if parent not in seen:
+                    schedule(visit, -parent)
+                    see(parent)
+
+    while visit:
+        current = -nextitem(visit)
+        if current >= stoprev:
+            yield current
+            for parent in parentrevs(current):
+                if parent not in seen:
+                    schedule(visit, -parent)
+                    see(parent)
+
 class lazyancestors(object):
     def __init__(self, pfunc, revs, stoprev=0, inclusive=False):
         """Create a new object generating ancestors for the given revs. Does
@@ -311,36 +342,9 @@
 
         If inclusive is True, the source revisions are also yielded. The
         reverse revision number order is still enforced."""
-        seen = {nullrev}
-        revs = self._initrevs
-
-        parentrevs = self._parentrevs
-        stoprev = self._stoprev
-        schedule = heapq.heappush
-        nextitem = heapq.heappop
-        see = seen.add
-
-        if self._inclusive:
-            visit = [-r for r in revs]
-            seen.update(revs)
-            heapq.heapify(visit)
-        else:
-            visit = []
-            heapq.heapify(visit)
-            for r in revs:
-                for parent in parentrevs(r):
-                    if parent not in seen:
-                        schedule(visit, -parent)
-                        see(parent)
-
-        while visit:
-            current = -nextitem(visit)
-            if current >= stoprev:
-                yield current
-                for parent in parentrevs(current):
-                    if parent not in seen:
-                        schedule(visit, -parent)
-                        see(parent)
+        for rev in _lazyancestorsiter(self._parentrevs, self._initrevs,
+                                      self._stoprev, self._inclusive):
+            yield rev
 
     def __contains__(self, target):
         """Test whether target is an ancestor of self._initrevs."""



To: martinvonz, #hg-reviewers
Cc: mercurial-devel


More information about the Mercurial-devel mailing list