ObjectStoreGraphWalker.ack: use non-recursive implementation rc-walker-ack-v5
authorTay Ray Chuan <rctay89@gmail.com>
Tue, 23 Mar 2010 18:56:23 +0000 (02:56 +0800)
committerTay Ray Chuan <rctay89@gmail.com>
Tue, 6 Apr 2010 14:57:38 +0000 (22:57 +0800)
We were recursively removing from self.heads; rewrite this such we try
removing heads this in a loop.

This gives a nice performance boost.

dulwich/object_store.py

index 1ad62fdc44721695369cda8ca1d8eec99f509f9b..9522c4b4610823c115cbe039eb82e050047d5c86 100644 (file)
@@ -706,11 +706,25 @@ class ObjectStoreGraphWalker(object):
 
     def ack(self, sha):
         """Ack that a revision and its ancestors are present in the source."""
-        if sha in self.heads:
-            self.heads.remove(sha)
-        if sha in self.parents:
-            for p in self.parents[sha]:
-                self.ack(p)
+        ancestors = set([sha])
+
+        # stop if we run out of heads to remove
+        while self.heads:
+            for a in ancestors:
+                if a in self.heads:
+                    self.heads.remove(a)
+
+            # collect all ancestors
+            new_ancestors = set()
+            for a in ancestors:
+                if a in self.parents:
+                    new_ancestors.update(self.parents[a])
+
+            # no more ancestors; stop
+            if not new_ancestors:
+                break
+
+            ancestors = new_ancestors
 
     def next(self):
         """Iterate over ancestors of heads in the target."""