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.
This commit is contained in:
parent
4be8b12207
commit
364d3dd208
29
file.go
29
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
|
||||
}
|
||||
|
|
52
file_test.go
52
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)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue