+ 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 ChunkSpec) {
+ req := Request{pp.Integer(piece.index), cs}
+ if !piece.endGame && !endGameIter && p.t.pendingRequests[req] > 0 {
+ return
+ }
+ interested = true
+ more = p.setInterested(true)
+ if !more {
+ return
+ }
+ if len(p.actualRequestState.Requests) >= p.nominalMaxRequests() {
+ return
+ }
+ if p.peerChoking && !p.peerAllowedFast.Contains(bitmap.BitIndex(req.Index)) {
+ return
+ }
+ var err error
+ more, err = p.request(req)
+ if err != nil {
+ panic(err)
+ }
+ })
+ if interested && len(p.actualRequestState.Requests) >= p.nominalMaxRequests() {
+ break
+ }
+ if !more {
+ break