fix: torrent file real time completed bytes

This commit is contained in:
liwei 2023-07-23 00:30:45 +08:00 committed by Matt Joiner
parent 4fdfcf8da2
commit ca5bd29a04
2 changed files with 49 additions and 20 deletions

65
file.go
View File

@ -62,31 +62,58 @@ func fileBytesLeft(
fileTorrentOffset int64, fileTorrentOffset int64,
fileLength int64, fileLength int64,
torrentCompletedPieces *roaring.Bitmap, torrentCompletedPieces *roaring.Bitmap,
pieceSizeCompletedFn func(pieceIndex int) int64,
) (left int64) { ) (left int64) {
numPiecesSpanned := fileEndPieceIndex - fileFirstPieceIndex if fileLength == 0 {
switch numPiecesSpanned { return
case 0:
case 1:
if !torrentCompletedPieces.Contains(bitmap.BitIndex(fileFirstPieceIndex)) {
left += fileLength
}
default:
if !torrentCompletedPieces.Contains(bitmap.BitIndex(fileFirstPieceIndex)) {
left += torrentUsualPieceSize - (fileTorrentOffset % torrentUsualPieceSize)
}
if !torrentCompletedPieces.Contains(bitmap.BitIndex(fileEndPieceIndex - 1)) {
left += fileTorrentOffset + fileLength - int64(fileEndPieceIndex-1)*torrentUsualPieceSize
}
completedMiddlePieces := torrentCompletedPieces.Clone()
completedMiddlePieces.RemoveRange(0, bitmap.BitRange(fileFirstPieceIndex+1))
completedMiddlePieces.RemoveRange(bitmap.BitRange(fileEndPieceIndex-1), bitmap.ToEnd)
left += int64(numPiecesSpanned-2-pieceIndex(completedMiddlePieces.GetCardinality())) * torrentUsualPieceSize
} }
noCompletedMiddlePieces := roaring.New()
noCompletedMiddlePieces.AddRange(bitmap.BitRange(fileFirstPieceIndex), bitmap.BitRange(fileEndPieceIndex))
noCompletedMiddlePieces.AndNot(torrentCompletedPieces)
noCompletedMiddlePieces.Iterate(func(pieceIndex uint32) bool {
i := int(pieceIndex)
pieceSizeCompleted := pieceSizeCompletedFn(i)
if i == fileFirstPieceIndex {
beginOffset := fileTorrentOffset % torrentUsualPieceSize
beginSize := torrentUsualPieceSize - beginOffset
beginDownLoaded := pieceSizeCompleted - beginOffset
if beginDownLoaded < 0 {
beginDownLoaded = 0
}
left += beginSize - beginDownLoaded
} else if i == fileEndPieceIndex-1 {
endSize := (fileTorrentOffset + fileLength) % torrentUsualPieceSize
if endSize == 0 {
endSize = torrentUsualPieceSize
}
endDownloaded := pieceSizeCompleted
if endDownloaded > endSize {
endDownloaded = endSize
}
left += endSize - endDownloaded
} else {
left += torrentUsualPieceSize - pieceSizeCompleted
}
return true
})
if left > fileLength {
left = fileLength
}
//
//numPiecesSpanned := f.EndPieceIndex() - f.BeginPieceIndex()
//completedMiddlePieces := f.t._completedPieces.Clone()
//completedMiddlePieces.RemoveRange(0, bitmap.BitRange(f.BeginPieceIndex()+1))
//completedMiddlePieces.RemoveRange(bitmap.BitRange(f.EndPieceIndex()-1), bitmap.ToEnd)
//left += int64(numPiecesSpanned-2-pieceIndex(completedMiddlePieces.GetCardinality())) * torrentUsualPieceSize
return return
} }
func (f *File) bytesLeft() (left int64) { func (f *File) bytesLeft() (left int64) {
return fileBytesLeft(int64(f.t.usualPieceSize()), f.BeginPieceIndex(), f.EndPieceIndex(), f.offset, f.length, &f.t._completedPieces) return fileBytesLeft(int64(f.t.usualPieceSize()), f.BeginPieceIndex(), f.EndPieceIndex(), f.offset, f.length, &f.t._completedPieces, func(pieceIndex int) int64 {
return int64(f.t.piece(pieceIndex).numDirtyBytes())
})
} }
// The relative file path for a multi-file torrent, and the torrent name for a // The relative file path for a multi-file torrent, and the torrent name for a

View File

@ -35,7 +35,9 @@ type testFileBytesLeft struct {
func (me testFileBytesLeft) Run(t *testing.T) { func (me testFileBytesLeft) Run(t *testing.T) {
t.Run(me.name, func(t *testing.T) { t.Run(me.name, func(t *testing.T) {
assert.EqualValues(t, me.expected, fileBytesLeft(me.usualPieceSize, me.firstPieceIndex, me.endPieceIndex, me.fileOffset, me.fileLength, &me.completedPieces)) assert.EqualValues(t, me.expected, fileBytesLeft(me.usualPieceSize, me.firstPieceIndex, me.endPieceIndex, me.fileOffset, me.fileLength, &me.completedPieces, func(pieceIndex int) int64 {
return 0
}))
}) })
} }