From: Matt Joiner Date: Tue, 24 Mar 2020 01:15:35 +0000 (+1100) Subject: Rewrite file.bytesLeft X-Git-Tag: v1.15.0~3 X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=364d3dd208311430e0ab5173d4d6328b9e6330b6;p=btrtrc.git Rewrite file.bytesLeft Avoids iteration, and should handle files that are entirely inside a single piece, as well as zero-sized at the beginning of a torrent. Should fix #387. --- diff --git a/file.go b/file.go index 1c54f20c..f0242400 100644 --- a/file.go +++ b/file.go @@ -62,21 +62,24 @@ func fileBytesLeft( fileLength int64, torrentCompletedPieces bitmap.Bitmap, ) (left int64) { - fileEndPieceIndex-- - bitmap.Flip(torrentCompletedPieces, fileFirstPieceIndex+1, fileEndPieceIndex).IterTyped(func(piece int) bool { - if piece >= fileEndPieceIndex { - return false + numPiecesSpanned := fileEndPieceIndex - fileFirstPieceIndex + switch numPiecesSpanned { + case 0: + case 1: + if !torrentCompletedPieces.Get(fileFirstPieceIndex) { + left += fileLength } - if piece > fileFirstPieceIndex { - left += torrentUsualPieceSize + default: + if !torrentCompletedPieces.Get(fileFirstPieceIndex) { + left += torrentUsualPieceSize - (fileTorrentOffset % torrentUsualPieceSize) } - return true - }) - if !torrentCompletedPieces.Get(fileFirstPieceIndex) { - left += torrentUsualPieceSize - (fileTorrentOffset % torrentUsualPieceSize) - } - if !torrentCompletedPieces.Get(fileEndPieceIndex) { - left += (fileTorrentOffset + fileLength) % torrentUsualPieceSize + if !torrentCompletedPieces.Get(fileEndPieceIndex - 1) { + left += fileTorrentOffset + fileLength - int64(fileEndPieceIndex-1)*torrentUsualPieceSize + } + completedMiddlePieces := torrentCompletedPieces.Copy() + completedMiddlePieces.RemoveRange(0, fileFirstPieceIndex+1) + completedMiddlePieces.RemoveRange(fileEndPieceIndex-1, bitmap.ToEnd) + left += int64(numPiecesSpanned-2-completedMiddlePieces.Len()) * torrentUsualPieceSize } return } diff --git a/file_test.go b/file_test.go index b4111268..0443cf3b 100644 --- a/file_test.go +++ b/file_test.go @@ -40,19 +40,31 @@ func (me testFileBytesLeft) Run(t *testing.T) { } func TestFileBytesLeft(t *testing.T) { + testFileBytesLeft{ - usualPieceSize: 2, + usualPieceSize: 3, firstPieceIndex: 1, endPieceIndex: 1, fileOffset: 1, + fileLength: 0, + expected: 0, + name: "ZeroLengthFile", + }.Run(t) + + testFileBytesLeft{ + usualPieceSize: 2, + firstPieceIndex: 1, + endPieceIndex: 2, + fileOffset: 1, fileLength: 1, expected: 1, + name: "EndOfSecondPiece", }.Run(t) testFileBytesLeft{ usualPieceSize: 3, firstPieceIndex: 0, - endPieceIndex: 0, + endPieceIndex: 1, fileOffset: 1, fileLength: 1, expected: 1, @@ -62,10 +74,44 @@ func TestFileBytesLeft(t *testing.T) { testFileBytesLeft{ usualPieceSize: 3, firstPieceIndex: 0, - endPieceIndex: 0, + endPieceIndex: 1, fileOffset: 1, fileLength: 1, expected: 1, name: "LandLocked", }.Run(t) + + testFileBytesLeft{ + usualPieceSize: 3, + firstPieceIndex: 1, + endPieceIndex: 3, + fileOffset: 4, + fileLength: 4, + expected: 4, + name: "TwoPieces", + }.Run(t) + + testFileBytesLeft{ + usualPieceSize: 3, + firstPieceIndex: 1, + endPieceIndex: 4, + fileOffset: 5, + fileLength: 7, + expected: 7, + name: "ThreePieces", + }.Run(t) + + testFileBytesLeft{ + usualPieceSize: 3, + firstPieceIndex: 1, + endPieceIndex: 4, + fileOffset: 5, + fileLength: 7, + expected: 0, + completedPieces: func() (ret bitmap.Bitmap) { + ret.AddRange(0, 5) + return + }(), + name: "ThreePiecesCompletedAll", + }.Run(t) }