]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Move piece allocation to its own func
authorMatt Joiner <anacrolix@gmail.com>
Thu, 13 May 2021 08:35:49 +0000 (18:35 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Mon, 7 Jun 2021 03:01:39 +0000 (13:01 +1000)
request-strategy/order.go

index 307e47efdd7814ab760dbf726747e693bb2cc6b9..da6890e583fd51c4b5e12b1578518ab389e6bafa 100644 (file)
@@ -133,94 +133,7 @@ func (requestOrder *ClientPieceOrder) DoRequests(torrents []*Torrent) map[PeerId
                if !p.Request {
                        continue
                }
-               peersForPiece := make([]*peersForPieceRequests, 0, len(allPeers[p.t]))
-               for _, peer := range allPeers[p.t] {
-                       peersForPiece = append(peersForPiece, &peersForPieceRequests{
-                               requestsInPiece: 0,
-                               requestsPeer:    peer,
-                       })
-               }
-               sortPeersForPiece := func() {
-                       sort.Slice(peersForPiece, func(i, j int) bool {
-                               return multiless.New().Int(
-                                       peersForPiece[i].requestsInPiece,
-                                       peersForPiece[j].requestsInPiece,
-                               ).Int(
-                                       peersForPiece[i].requestablePiecesRemaining,
-                                       peersForPiece[j].requestablePiecesRemaining,
-                               ).Float64(
-                                       peersForPiece[j].DownloadRate,
-                                       peersForPiece[i].DownloadRate,
-                               ).Int64(
-                                       int64(peersForPiece[j].Age), int64(peersForPiece[i].Age),
-                                       // TODO: Probably peer priority can come next
-                               ).Uintptr(
-                                       peersForPiece[i].Id.Uintptr(),
-                                       peersForPiece[j].Id.Uintptr(),
-                               ).MustLess()
-                       })
-               }
-               pendingChunksRemaining := int(p.NumPendingChunks)
-               if f := torrentPiece.IterPendingChunks; f != nil {
-                       f(func(chunk types.ChunkSpec) {
-                               req := Request{pp.Integer(p.index), chunk}
-                               defer func() { pendingChunksRemaining-- }()
-                               sortPeersForPiece()
-                               skipped := 0
-                               // Try up to the number of peers that could legitimately receive the request equal to
-                               // the number of chunks left. This should ensure that only the best peers serve the last
-                               // few chunks in a piece.
-                               lowestNumRequestsInPiece := math.MaxInt16
-                               for _, peer := range peersForPiece {
-                                       if !peer.canFitRequest() || !peer.HasPiece(p.index) || (!peer.pieceAllowedFastOrDefault(p.index) && peer.Choking) {
-                                               continue
-                                       }
-                                       if skipped+1 >= pendingChunksRemaining {
-                                               break
-                                       }
-                                       if f := peer.HasExistingRequest; f == nil || !f(req) {
-                                               skipped++
-                                               lowestNumRequestsInPiece = peer.requestsInPiece
-                                               continue
-                                       }
-                                       if peer.requestsInPiece > lowestNumRequestsInPiece {
-                                               break
-                                       }
-                                       if !peer.pieceAllowedFastOrDefault(p.index) {
-                                               // We must stay interested for this.
-                                               peer.nextState.Interested = true
-                                       }
-                                       peer.addNextRequest(req)
-                                       return
-                               }
-                               for _, peer := range peersForPiece {
-                                       if !peer.canFitRequest() {
-                                               continue
-                                       }
-                                       if !peer.HasPiece(p.index) {
-                                               continue
-                                       }
-                                       if !peer.pieceAllowedFastOrDefault(p.index) {
-                                               // TODO: Verify that's okay to stay uninterested if we request allowed fast
-                                               // pieces.
-                                               peer.nextState.Interested = true
-                                               if peer.Choking {
-                                                       continue
-                                               }
-                                       }
-                                       peer.addNextRequest(req)
-                                       return
-                               }
-                       })
-               }
-               if pendingChunksRemaining != 0 {
-                       panic(pendingChunksRemaining)
-               }
-               for _, peer := range peersForPiece {
-                       if peer.canRequestPiece(p.index) {
-                               peer.requestablePiecesRemaining--
-                       }
-               }
+               allocatePendingChunks(p, allPeers[p.t])
        }
        ret := make(map[PeerId]PeerNextRequestState)
        for _, peers := range allPeers {
@@ -233,3 +146,94 @@ func (requestOrder *ClientPieceOrder) DoRequests(torrents []*Torrent) map[PeerId
        }
        return ret
 }
+
+func allocatePendingChunks(p pieceRequestOrderPiece, peers []*requestsPeer) {
+       peersForPiece := make([]*peersForPieceRequests, 0, len(peers))
+       for _, peer := range peers {
+               peersForPiece = append(peersForPiece, &peersForPieceRequests{
+                       requestsInPiece: 0,
+                       requestsPeer:    peer,
+               })
+       }
+       sortPeersForPiece := func() {
+               sort.Slice(peersForPiece, func(i, j int) bool {
+                       return multiless.New().Int(
+                               peersForPiece[i].requestsInPiece,
+                               peersForPiece[j].requestsInPiece,
+                       ).Int(
+                               peersForPiece[i].requestablePiecesRemaining,
+                               peersForPiece[j].requestablePiecesRemaining,
+                       ).Float64(
+                               peersForPiece[j].DownloadRate,
+                               peersForPiece[i].DownloadRate,
+                       ).Int64(
+                               int64(peersForPiece[j].Age), int64(peersForPiece[i].Age),
+                               // TODO: Probably peer priority can come next
+                       ).Uintptr(
+                               peersForPiece[i].Id.Uintptr(),
+                               peersForPiece[j].Id.Uintptr(),
+                       ).MustLess()
+               })
+       }
+       pendingChunksRemaining := int(p.NumPendingChunks)
+       if f := p.IterPendingChunks; f != nil {
+               f(func(chunk types.ChunkSpec) {
+                       req := Request{pp.Integer(p.index), chunk}
+                       defer func() { pendingChunksRemaining-- }()
+                       sortPeersForPiece()
+                       skipped := 0
+                       // Try up to the number of peers that could legitimately receive the request equal to
+                       // the number of chunks left. This should ensure that only the best peers serve the last
+                       // few chunks in a piece.
+                       lowestNumRequestsInPiece := math.MaxInt16
+                       for _, peer := range peersForPiece {
+                               if !peer.canFitRequest() || !peer.HasPiece(p.index) || (!peer.pieceAllowedFastOrDefault(p.index) && peer.Choking) {
+                                       continue
+                               }
+                               if skipped+1 >= pendingChunksRemaining {
+                                       break
+                               }
+                               if f := peer.HasExistingRequest; f == nil || !f(req) {
+                                       skipped++
+                                       lowestNumRequestsInPiece = peer.requestsInPiece
+                                       continue
+                               }
+                               if peer.requestsInPiece > lowestNumRequestsInPiece {
+                                       break
+                               }
+                               if !peer.pieceAllowedFastOrDefault(p.index) {
+                                       // We must stay interested for this.
+                                       peer.nextState.Interested = true
+                               }
+                               peer.addNextRequest(req)
+                               return
+                       }
+                       for _, peer := range peersForPiece {
+                               if !peer.canFitRequest() {
+                                       continue
+                               }
+                               if !peer.HasPiece(p.index) {
+                                       continue
+                               }
+                               if !peer.pieceAllowedFastOrDefault(p.index) {
+                                       // TODO: Verify that's okay to stay uninterested if we request allowed fast
+                                       // pieces.
+                                       peer.nextState.Interested = true
+                                       if peer.Choking {
+                                               continue
+                                       }
+                               }
+                               peer.addNextRequest(req)
+                               return
+                       }
+               })
+       }
+       if pendingChunksRemaining != 0 {
+               panic(pendingChunksRemaining)
+       }
+       for _, peer := range peersForPiece {
+               if peer.canRequestPiece(p.index) {
+                       peer.requestablePiecesRemaining--
+               }
+       }
+}