Fix major issues with task computation logic
authorJakob Cornell <jakob+gpg@jcornell.net>
Sat, 6 Nov 2021 16:05:03 +0000 (11:05 -0500)
committerJakob Cornell <jakob+gpg@jcornell.net>
Sat, 6 Nov 2021 16:05:03 +0000 (11:05 -0500)
src/disk_jumble/verify.py

index 34bc6eb408e24d35da47333b937fc31c76a113cd..e427c48af792fa7371c9da0971b8fea32f545a51 100644 (file)
@@ -63,34 +63,35 @@ if __name__ == "__main__":
                        use_hasher = None
                        chunks = []
                        for (slab, hasher_ref) in group:
-                               slab_end = slab.entity_offset + len(slab.sectors) * disk.sector_size
-
-                               if offset is not None and slab.entity_offset > offset:
-                                       if chunks:
-                                               tasks.append(_PieceTask(entity_id, offset // piece_len, use_hasher, chunks, False))
-                                       offset = None
-                                       use_hasher = None
-                                       chunks = []
-
-                               if offset is None:
-                                       aligned = math.ceil(slab.entity_offset / piece_len) * piece_len
-                                       if hasher_ref and hasher_ref.entity_offset < aligned:
-                                               assert hasher_ref.entity_offset < torrent_len
-                                               use_hasher = hasher_ref
-                                               offset = hasher_ref.entity_offset
-                                       elif aligned < min(slab_end, torrent_len):
-                                               offset = aligned
-
-                               if offset is not None:
-                                       piece_end = min(offset + piece_len - offset % piece_len, torrent_len)
-                                       chunk_end = min(piece_end, slab_end)
-                                       chunks.append(_SlabChunk(slab, slice(offset - slab.entity_offset, chunk_end - slab.entity_offset)))
-                                       if chunk_end == piece_end:
-                                               tasks.append(_PieceTask(entity_id, offset // piece_len, use_hasher, chunks, True))
+                               slab_end = min(slab.entity_offset + len(slab.sectors) * disk.sector_size, torrent_len)
+
+                               while offset is None or offset < slab_end:
+                                       if offset is not None and slab.entity_offset > offset:
+                                               if chunks:
+                                                       tasks.append(_PieceTask(entity_id, offset // piece_len, use_hasher, chunks, False))
                                                offset = None
                                                use_hasher = None
                                                chunks = []
-                                       else:
+
+                                       if offset is None:
+                                               aligned = math.ceil(slab.entity_offset / piece_len) * piece_len
+                                               if hasher_ref and hasher_ref.entity_offset < aligned:
+                                                       assert hasher_ref.entity_offset < torrent_len
+                                                       use_hasher = hasher_ref
+                                                       offset = hasher_ref.entity_offset
+                                               elif aligned < slab_end:
+                                                       offset = aligned
+                                               else:
+                                                       break  # no usable data in this slab
+
+                                       if offset is not None:
+                                               piece_end = min(offset + piece_len - offset % piece_len, torrent_len)
+                                               chunk_end = min(piece_end, slab_end)
+                                               chunks.append(_SlabChunk(slab, slice(offset - slab.entity_offset, chunk_end - slab.entity_offset)))
+                                               if chunk_end == piece_end:
+                                                       tasks.append(_PieceTask(entity_id, offset // piece_len, use_hasher, chunks, True))
+                                                       use_hasher = None
+                                                       chunks = []
                                                offset = chunk_end
 
                        if chunks: