]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Reduce the diff to master and add peerRequesting feature const
authorMatt Joiner <anacrolix@gmail.com>
Mon, 20 Sep 2021 05:09:28 +0000 (15:09 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Mon, 20 Sep 2021 05:09:28 +0000 (15:09 +1000)
client.go
peerconn.go
requesting.go
torrent.go

index 1a4c1a50ecc1e438a2d30ab74d5a42f2300768a0..e7683016b2ae2e14d110b43d5626f6730ee21e64 100644 (file)
--- a/client.go
+++ b/client.go
@@ -305,7 +305,9 @@ func NewClient(cfg *ClientConfig) (cl *Client, err error) {
                },
        }
 
-       //go cl.requester()
+       if !peerRequesting {
+               go cl.requester()
+       }
 
        return
 }
index 1b9bdbc1d2bd4b9a5dfb903eea0b5467e15bf110..8d3f6d819f84fdd72c37c6d7539e8755fe744218 100644 (file)
@@ -655,10 +655,14 @@ func (cn *PeerConn) postBitfield() {
 }
 
 func (cn *PeerConn) updateRequests() {
-       if cn.actualRequestState.Requests.GetCardinality() != 0 {
+       if peerRequesting {
+               if cn.actualRequestState.Requests.GetCardinality() != 0 {
+                       return
+               }
+               cn.tickleWriter()
                return
        }
-       cn.tickleWriter()
+       cn.t.cl.tickleRequester()
 }
 
 // Emits the indices in the Bitmaps bms in order, never repeating any index.
index 9f896738562afc4b42458010ccd35c4770ea369a..2c7b4582452c8c3012a3bf36b0a8bcbc2fa74342 100644 (file)
@@ -10,6 +10,9 @@ import (
        request_strategy "github.com/anacrolix/torrent/request-strategy"
 )
 
+// Calculate requests individually for each peer.
+const peerRequesting = true
+
 func (cl *Client) requester() {
        for {
                update := func() chansync.Signaled {
@@ -43,7 +46,9 @@ func (cl *Client) getRequestStrategyInput() request_strategy.Input {
        ts := make([]request_strategy.Torrent, 0, len(cl.torrents))
        for _, t := range cl.torrents {
                if !t.haveInfo() {
-                       // This would be removed if metadata is handled here.
+                       // This would be removed if metadata is handled here. We have to guard against not
+                       // knowing the piece size. If we have no info, we have no pieces too, so the end result
+                       // is the same.
                        continue
                }
                rst := request_strategy.Torrent{
@@ -126,72 +131,107 @@ type RequestIndex = request_strategy.RequestIndex
 type chunkIndexType = request_strategy.ChunkIndex
 
 func (p *Peer) applyNextRequestState() bool {
-       if p.actualRequestState.Requests.GetCardinality() > uint64(p.nominalMaxRequests()/2) {
-               return true
-       }
-       type piece struct {
-               index   int
-               endGame bool
-       }
-       var pieceOrder []piece
-       request_strategy.GetRequestablePieces(
-               p.t.cl.getRequestStrategyInput(),
-               func(t *request_strategy.Torrent, rsp *request_strategy.Piece, pieceIndex int) {
-                       if t.InfoHash != p.t.infoHash {
-                               return
-                       }
-                       if !p.peerHasPiece(pieceIndex) {
-                               return
-                       }
-                       pieceOrder = append(pieceOrder, piece{
-                               index:   pieceIndex,
-                               endGame: rsp.Priority == PiecePriorityNow,
-                       })
-               },
-       )
-       more := true
-       interested := false
-       for _, endGameIter := range []bool{false, true} {
-               for _, piece := range pieceOrder {
-                       tp := p.t.piece(piece.index)
-                       tp.iterUndirtiedChunks(func(cs chunkIndexType) {
-                               req := cs + tp.requestIndexOffset()
-                               if !piece.endGame && !endGameIter && p.t.pendingRequests[req] > 0 {
-                                       return
-                               }
-                               interested = true
-                               more = p.setInterested(true)
-                               if !more {
+       if peerRequesting {
+               if p.actualRequestState.Requests.GetCardinality() > uint64(p.nominalMaxRequests()/2) {
+                       return true
+               }
+               type piece struct {
+                       index   int
+                       endGame bool
+               }
+               var pieceOrder []piece
+               request_strategy.GetRequestablePieces(
+                       p.t.cl.getRequestStrategyInput(),
+                       func(t *request_strategy.Torrent, rsp *request_strategy.Piece, pieceIndex int) {
+                               if t.InfoHash != p.t.infoHash {
                                        return
                                }
-                               if maxRequests(p.actualRequestState.Requests.GetCardinality()) >= p.nominalMaxRequests() {
+                               if !p.peerHasPiece(pieceIndex) {
                                        return
                                }
-                               if p.peerChoking && !p.peerAllowedFast.Contains(bitmap.BitIndex(piece.index)) {
-                                       return
+                               pieceOrder = append(pieceOrder, piece{
+                                       index:   pieceIndex,
+                                       endGame: rsp.Priority == PiecePriorityNow,
+                               })
+                       },
+               )
+               more := true
+               interested := false
+               for _, endGameIter := range []bool{false, true} {
+                       for _, piece := range pieceOrder {
+                               tp := p.t.piece(piece.index)
+                               tp.iterUndirtiedChunks(func(cs chunkIndexType) {
+                                       req := cs + tp.requestIndexOffset()
+                                       if !piece.endGame && !endGameIter && p.t.pendingRequests[req] > 0 {
+                                               return
+                                       }
+                                       interested = true
+                                       more = p.setInterested(true)
+                                       if !more {
+                                               return
+                                       }
+                                       if maxRequests(p.actualRequestState.Requests.GetCardinality()) >= p.nominalMaxRequests() {
+                                               return
+                                       }
+                                       if p.peerChoking && !p.peerAllowedFast.Contains(bitmap.BitIndex(piece.index)) {
+                                               return
+                                       }
+                                       var err error
+                                       more, err = p.request(req)
+                                       if err != nil {
+                                               panic(err)
+                                       }
+                               })
+                               if interested && maxRequests(p.actualRequestState.Requests.GetCardinality()) >= p.nominalMaxRequests() {
+                                       break
                                }
-                               var err error
-                               more, err = p.request(req)
-                               if err != nil {
-                                       panic(err)
+                               if !more {
+                                       break
                                }
-                       })
-                       if interested && maxRequests(p.actualRequestState.Requests.GetCardinality()) >= p.nominalMaxRequests() {
-                               break
                        }
                        if !more {
                                break
                        }
                }
                if !more {
-                       break
+                       return false
+               }
+               if !interested {
+                       p.setInterested(false)
                }
+               return more
        }
-       if !more {
+
+       next := p.nextRequestState
+       current := p.actualRequestState
+       if !p.setInterested(next.Interested) {
                return false
        }
-       if !interested {
-               p.setInterested(false)
+       more := true
+       current.Requests.Iterate(func(req uint32) bool {
+               if !next.Requests.Contains(req) {
+                       more = p.cancel(req)
+                       return more
+               }
+               return true
+       })
+       if !more {
+               return false
        }
+       next.Requests.Iterate(func(req uint32) bool {
+               // This could happen if the peer chokes us between the next state being generated, and us
+               // trying to transmit the state.
+               if p.peerChoking && !p.peerAllowedFast.Contains(bitmap.BitIndex(req/p.t.chunksPerRegularPiece())) {
+                       return true
+               }
+               var err error
+               more, err = p.request(req)
+               if err != nil {
+                       panic(err)
+               } /* else {
+                       log.Print(req)
+               } */
+               return more
+       })
        return more
 }
index bf7968cf0671f0db2996cb833a2960e076f1afb9..370865e6bee24c974ec1883e79a23cfffbea8936 100644 (file)
@@ -842,14 +842,14 @@ func (t *Torrent) bitfield() (bf []bool) {
        return
 }
 
-func (t *Torrent) chunksPerRegularPiece() uint32 {
-       return uint32((pp.Integer(t.usualPieceSize()) + t.chunkSize - 1) / t.chunkSize)
-}
-
 func (t *Torrent) pieceNumChunks(piece pieceIndex) chunkIndexType {
        return chunkIndexType((t.pieceLength(piece) + t.chunkSize - 1) / t.chunkSize)
 }
 
+func (t *Torrent) chunksPerRegularPiece() uint32 {
+       return uint32((pp.Integer(t.usualPieceSize()) + t.chunkSize - 1) / t.chunkSize)
+}
+
 func (t *Torrent) pendAllChunkSpecs(pieceIndex pieceIndex) {
        t.pieces[pieceIndex]._dirtyChunks.Clear()
 }