소스 검색

Rewrite PackData._follow_chain to iterate rather than recurse.

A test needed to be fixed to cope with the new breadth-first order.
William Grant 9 년 전
부모
커밋
57ef430c21
2개의 변경된 파일11개의 추가작업 그리고 10개의 파일을 삭제
  1. 10 9
      dulwich/pack.py
  2. 1 1
      dulwich/tests/test_pack.py

+ 10 - 9
dulwich/pack.py

@@ -1337,15 +1337,16 @@ class DeltaChainIterator(object):
     def _follow_chain(self, offset, obj_type_num, base_chunks):
         # Unlike PackData.get_object_at, there is no need to cache offsets as
         # this approach by design inflates each object exactly once.
-        unpacked = self._resolve_object(offset, obj_type_num, base_chunks)
-        yield self._result(unpacked)
-
-        pending = chain(self._pending_ofs.pop(unpacked.offset, []),
-                        self._pending_ref.pop(unpacked.sha(), []))
-        for new_offset in pending:
-            for new_result in self._follow_chain(
-              new_offset, unpacked.obj_type_num, unpacked.obj_chunks):
-                yield new_result
+        todo = [(offset, obj_type_num, base_chunks)]
+        for offset, obj_type_num, base_chunks in todo:
+            unpacked = self._resolve_object(offset, obj_type_num, base_chunks)
+            yield self._result(unpacked)
+
+            unblocked = chain(self._pending_ofs.pop(unpacked.offset, []),
+                              self._pending_ref.pop(unpacked.sha(), []))
+            todo.extend(
+                (new_offset, unpacked.obj_type_num, unpacked.obj_chunks)
+                for new_offset in unblocked)
 
     def __iter__(self):
         return self._walk_all_chains()

+ 1 - 1
dulwich/tests/test_pack.py

@@ -924,7 +924,7 @@ class DeltaChainIteratorTests(TestCase):
             (OFS_DELTA, (1, b'blob3')),
             (OFS_DELTA, (0, b'bob')),
         ])
-        self.assertEntriesMatch([0, 2, 1, 3, 4], entries,
+        self.assertEntriesMatch([0, 2, 4, 1, 3], entries,
                                 self.make_pack_iter(f))
 
     def test_long_chain(self):