]> Sergey Matveev's repositories - btrtrc.git/blobdiff - piece.go
Drop support for go 1.20
[btrtrc.git] / piece.go
index 411b187c61c4026a70d1d377af296f43317ab95b..e08b2609690e385663c4df716d22d05ab3c7808b 100644 (file)
--- a/piece.go
+++ b/piece.go
@@ -1,14 +1,11 @@
 package torrent
 
 import (
-       "encoding/gob"
        "fmt"
        "sync"
 
-       "github.com/RoaringBitmap/roaring"
        "github.com/anacrolix/chansync"
        "github.com/anacrolix/missinggo/v2/bitmap"
-       request_strategy "github.com/anacrolix/torrent/request-strategy"
 
        "github.com/anacrolix/torrent/metainfo"
        pp "github.com/anacrolix/torrent/peer_protocol"
@@ -31,7 +28,10 @@ type Piece struct {
 
        publicPieceState PieceState
        priority         piecePriority
-       availability     int64
+       // Availability adjustment for this piece relative to len(Torrent.connsWithAllPieces). This is
+       // incremented for any piece a peer has when a peer has a piece, Torrent.haveInfo is true, and
+       // the Peer isn't recorded in Torrent.connsWithAllPieces.
+       relativeAvailability int
 
        // This can be locked when the Client lock is taken, but probably not vice versa.
        pendingWritesMutex sync.Mutex
@@ -55,6 +55,12 @@ func (p *Piece) Storage() storage.Piece {
        return p.t.storage.Piece(p.Info())
 }
 
+func (p *Piece) Flush() {
+       if p.t.storage.Flush != nil {
+               _ = p.t.storage.Flush()
+       }
+}
+
 func (p *Piece) pendingChunkIndex(chunkIndex chunkIndexType) bool {
        return !p.chunkIndexDirty(chunkIndex)
 }
@@ -68,7 +74,7 @@ func (p *Piece) hasDirtyChunks() bool {
 }
 
 func (p *Piece) numDirtyChunks() chunkIndexType {
-       return chunkIndexType(roaringBitmapRangeCardinality(
+       return chunkIndexType(roaringBitmapRangeCardinality[RequestIndex](
                &p.t.dirtyChunks,
                p.requestIndexOffset(),
                p.t.pieceRequestIndexOffset(p.index+1)))
@@ -76,11 +82,13 @@ func (p *Piece) numDirtyChunks() chunkIndexType {
 
 func (p *Piece) unpendChunkIndex(i chunkIndexType) {
        p.t.dirtyChunks.Add(p.requestIndexOffset() + i)
+       p.t.updatePieceRequestOrder(p.index)
        p.readerCond.Broadcast()
 }
 
 func (p *Piece) pendChunkIndex(i RequestIndex) {
        p.t.dirtyChunks.Remove(p.requestIndexOffset() + i)
+       p.t.updatePieceRequestOrder(p.index)
 }
 
 func (p *Piece) numChunks() chunkIndexType {
@@ -163,10 +171,10 @@ func (p *Piece) VerifyData() {
        if p.hashing {
                target++
        }
-       //log.Printf("target: %d", target)
+       // log.Printf("target: %d", target)
        p.t.queuePieceCheck(p.index)
        for {
-               //log.Printf("got %d verifies", p.numVerifies)
+               // log.Printf("got %d verifies", p.numVerifies)
                if p.numVerifies >= target {
                        break
                }
@@ -240,61 +248,10 @@ func (p *Piece) State() PieceState {
        return p.t.PieceState(p.index)
 }
 
-func init() {
-       gob.Register(undirtiedChunksIter{})
-}
-
-type undirtiedChunksIter struct {
-       TorrentDirtyChunks *roaring.Bitmap
-       StartRequestIndex  RequestIndex
-       EndRequestIndex    RequestIndex
-}
-
-func (me undirtiedChunksIter) Iter(f func(chunkIndexType)) {
-       it := me.TorrentDirtyChunks.Iterator()
-       startIndex := me.StartRequestIndex
-       endIndex := me.EndRequestIndex
-       it.AdvanceIfNeeded(startIndex)
-       lastDirty := startIndex - 1
-       for it.HasNext() {
-               next := it.Next()
-               if next >= endIndex {
-                       break
-               }
-               for index := lastDirty + 1; index < next; index++ {
-                       f(index - startIndex)
-               }
-               lastDirty = next
-       }
-       for index := lastDirty + 1; index < endIndex; index++ {
-               f(index - startIndex)
-       }
-       return
-}
-
-func (p *Piece) undirtiedChunksIter() request_strategy.ChunksIter {
-       // Use an iterator to jump between dirty bits.
-       return undirtiedChunksIter{
-               TorrentDirtyChunks: &p.t.dirtyChunks,
-               StartRequestIndex:  p.requestIndexOffset(),
-               EndRequestIndex:    p.requestIndexOffset() + p.numChunks(),
-       }
-}
-
-func (p *Piece) iterUndirtiedChunks(f func(chunkIndexType)) {
-       if true {
-               p.undirtiedChunksIter().Iter(f)
-               return
-       }
-       // The original implementation.
-       for i := chunkIndexType(0); i < p.numChunks(); i++ {
-               if p.chunkIndexDirty(i) {
-                       continue
-               }
-               f(i)
-       }
-}
-
 func (p *Piece) requestIndexOffset() RequestIndex {
        return p.t.pieceRequestIndexOffset(p.index)
 }
+
+func (p *Piece) availability() int {
+       return len(p.t.connsWithAllPieces) + p.relativeAvailability
+}