]> Sergey Matveev's repositories - btrtrc.git/commitdiff
fix: torrent file real time completed bytes
authorliwei <liwei-8466@qq.com>
Sat, 22 Jul 2023 16:30:45 +0000 (00:30 +0800)
committerMatt Joiner <anacrolix@gmail.com>
Sun, 23 Jul 2023 06:43:26 +0000 (16:43 +1000)
file.go
file_test.go

diff --git a/file.go b/file.go
index ed2f5da9ced0e74c87a903d1b160a3793331701d..bea4b13655d6024915434eecc66eeb0cab6524ad 100644 (file)
--- a/file.go
+++ b/file.go
@@ -62,31 +62,58 @@ func fileBytesLeft(
        fileTorrentOffset int64,
        fileLength int64,
        torrentCompletedPieces *roaring.Bitmap,
+       pieceSizeCompletedFn func(pieceIndex int) int64,
 ) (left int64) {
-       numPiecesSpanned := fileEndPieceIndex - fileFirstPieceIndex
-       switch numPiecesSpanned {
-       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
+       if fileLength == 0 {
+               return
+       }
+
+       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
                }
-               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
+               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
 }
 
 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
index e0df62b41ade8b9c8bf4a1868b4009c3fe6d3030..2f57bcf46ae3d747f499598eeb1116dcb2015df7 100644 (file)
@@ -35,7 +35,9 @@ type testFileBytesLeft struct {
 
 func (me testFileBytesLeft) Run(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
+               }))
        })
 }