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,
|
fileLength int64,
|
||||||
torrentCompletedPieces bitmap.Bitmap,
|
torrentCompletedPieces bitmap.Bitmap,
|
||||||
) (left int64) {
|
) (left int64) {
|
||||||
fileEndPieceIndex--
|
numPiecesSpanned := fileEndPieceIndex - fileFirstPieceIndex
|
||||||
bitmap.Flip(torrentCompletedPieces, fileFirstPieceIndex+1, fileEndPieceIndex).IterTyped(func(piece int) bool {
|
switch numPiecesSpanned {
|
||||||
if piece >= fileEndPieceIndex {
|
case 0:
|
||||||
return false
|
case 1:
|
||||||
|
if !torrentCompletedPieces.Get(fileFirstPieceIndex) {
|
||||||
|
left += fileLength
|
||||||
}
|
}
|
||||||
if piece > fileFirstPieceIndex {
|
default:
|
||||||
left += torrentUsualPieceSize
|
if !torrentCompletedPieces.Get(fileFirstPieceIndex) {
|
||||||
|
left += torrentUsualPieceSize - (fileTorrentOffset % torrentUsualPieceSize)
|
||||||
}
|
}
|
||||||
return true
|
if !torrentCompletedPieces.Get(fileEndPieceIndex - 1) {
|
||||||
})
|
left += fileTorrentOffset + fileLength - int64(fileEndPieceIndex-1)*torrentUsualPieceSize
|
||||||
if !torrentCompletedPieces.Get(fileFirstPieceIndex) {
|
}
|
||||||
left += torrentUsualPieceSize - (fileTorrentOffset % torrentUsualPieceSize)
|
completedMiddlePieces := torrentCompletedPieces.Copy()
|
||||||
}
|
completedMiddlePieces.RemoveRange(0, fileFirstPieceIndex+1)
|
||||||
if !torrentCompletedPieces.Get(fileEndPieceIndex) {
|
completedMiddlePieces.RemoveRange(fileEndPieceIndex-1, bitmap.ToEnd)
|
||||||
left += (fileTorrentOffset + fileLength) % torrentUsualPieceSize
|
left += int64(numPiecesSpanned-2-completedMiddlePieces.Len()) * torrentUsualPieceSize
|
||||||
}
|
}
|
||||||
return
|
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) {
|
func TestFileBytesLeft(t *testing.T) {
|
||||||
|
|
||||||
testFileBytesLeft{
|
testFileBytesLeft{
|
||||||
usualPieceSize: 2,
|
usualPieceSize: 3,
|
||||||
firstPieceIndex: 1,
|
firstPieceIndex: 1,
|
||||||
endPieceIndex: 1,
|
endPieceIndex: 1,
|
||||||
fileOffset: 1,
|
fileOffset: 1,
|
||||||
|
fileLength: 0,
|
||||||
|
expected: 0,
|
||||||
|
name: "ZeroLengthFile",
|
||||||
|
}.Run(t)
|
||||||
|
|
||||||
|
testFileBytesLeft{
|
||||||
|
usualPieceSize: 2,
|
||||||
|
firstPieceIndex: 1,
|
||||||
|
endPieceIndex: 2,
|
||||||
|
fileOffset: 1,
|
||||||
fileLength: 1,
|
fileLength: 1,
|
||||||
expected: 1,
|
expected: 1,
|
||||||
|
name: "EndOfSecondPiece",
|
||||||
}.Run(t)
|
}.Run(t)
|
||||||
|
|
||||||
testFileBytesLeft{
|
testFileBytesLeft{
|
||||||
usualPieceSize: 3,
|
usualPieceSize: 3,
|
||||||
firstPieceIndex: 0,
|
firstPieceIndex: 0,
|
||||||
endPieceIndex: 0,
|
endPieceIndex: 1,
|
||||||
fileOffset: 1,
|
fileOffset: 1,
|
||||||
fileLength: 1,
|
fileLength: 1,
|
||||||
expected: 1,
|
expected: 1,
|
||||||
|
@ -62,10 +74,44 @@ func TestFileBytesLeft(t *testing.T) {
|
||||||
testFileBytesLeft{
|
testFileBytesLeft{
|
||||||
usualPieceSize: 3,
|
usualPieceSize: 3,
|
||||||
firstPieceIndex: 0,
|
firstPieceIndex: 0,
|
||||||
endPieceIndex: 0,
|
endPieceIndex: 1,
|
||||||
fileOffset: 1,
|
fileOffset: 1,
|
||||||
fileLength: 1,
|
fileLength: 1,
|
||||||
expected: 1,
|
expected: 1,
|
||||||
name: "LandLocked",
|
name: "LandLocked",
|
||||||
}.Run(t)
|
}.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