From 4088e847f3dbda1ba768462f7bb9debbbd3782e1 Mon Sep 17 00:00:00 2001
From: Matt Joiner <anacrolix@gmail.com>
Date: Wed, 1 Dec 2021 15:20:42 +1100
Subject: [PATCH] Provide mapping from infohash to Torrent in Input

---
 request-strategy/order.go | 51 +++------------------------------------
 requesting.go             | 21 ++++------------
 2 files changed, 8 insertions(+), 64 deletions(-)

diff --git a/request-strategy/order.go b/request-strategy/order.go
index cacd7f96..adbd29e4 100644
--- a/request-strategy/order.go
+++ b/request-strategy/order.go
@@ -3,7 +3,6 @@ package request_strategy
 import (
 	"bytes"
 	"expvar"
-	"log"
 	"runtime"
 	"sort"
 	"sync"
@@ -207,44 +206,6 @@ type pieceOrderingFinalizer struct {
 
 // Calls f with requestable pieces in order.
 func GetRequestablePieces(input Input, pro *PieceRequestOrder, f func(t *Torrent, p *Piece, pieceIndex int)) {
-	if false {
-		maxPieces := 0
-		for i := range input.Torrents {
-			maxPieces += len(input.Torrents[i].Pieces)
-		}
-		pieces := make([]filterPiece, 0, maxPieces)
-		for _t := range input.Torrents {
-			// TODO: We could do metainfo requests here.
-			t := &input.Torrents[_t]
-			for i := range t.Pieces {
-				pieces = append(pieces, filterPiece{
-					t:     &input.Torrents[_t],
-					index: i,
-					Piece: &t.Pieces[i],
-				})
-			}
-		}
-		pieces = getSortedFilterPieces(pieces)
-		{
-			if len(pieces) != pro.tree.Len() {
-				panic("length doesn't match")
-			}
-			pieces := pieces
-			pro.tree.Ascend(func(i btree.Item) bool {
-				_i := i.(pieceRequestOrderItem)
-				ii := pieceOrderInput{
-					_i.state,
-					_i.key,
-				}
-				if pieces[0].toPieceOrderInput() != ii {
-					panic(_i)
-				}
-				pieces = pieces[1:]
-				return true
-			})
-		}
-		log.Printf("%v pieces passed", len(pieces))
-	}
 	// Storage capacity left for this run, keyed by the storage capacity pointer on the storage
 	// TorrentImpl. A nil value means no capacity limit.
 	var storageLeft *int64
@@ -256,14 +217,8 @@ func GetRequestablePieces(input Input, pro *PieceRequestOrder, f func(t *Torrent
 	torrentUnverifiedBytes := map[metainfo.Hash]int64{}
 	pro.tree.Ascend(func(i btree.Item) bool {
 		_i := i.(pieceRequestOrderItem)
-		var piece *Piece
-		var t Torrent
-		for _, t = range input.Torrents {
-			if t.InfoHash == _i.key.InfoHash {
-				piece = &t.Pieces[_i.key.Index]
-				break
-			}
-		}
+		var t Torrent = input.Torrents[_i.key.InfoHash]
+		var piece *Piece = &t.Pieces[_i.key.Index]
 		if left := storageLeft; left != nil {
 			if *left < piece.Length {
 				return true
@@ -294,7 +249,7 @@ type Input struct {
 	// This is all torrents that share the same capacity below (or likely a single torrent if there
 	// is infinite capacity, since you could just run it separately for each Torrent if that's the
 	// case).
-	Torrents []Torrent
+	Torrents map[metainfo.Hash]Torrent
 	// Must not be modified. Non-nil if capacity is not infinite, meaning that pieces of torrents
 	// that share the same capacity key must be incorporated in piece ordering.
 	Capacity *int64
diff --git a/requesting.go b/requesting.go
index 147e574d..1e95cbcf 100644
--- a/requesting.go
+++ b/requesting.go
@@ -12,6 +12,7 @@ import (
 
 	"github.com/anacrolix/log"
 	"github.com/anacrolix/multiless"
+	"github.com/anacrolix/torrent/metainfo"
 
 	request_strategy "github.com/anacrolix/torrent/request-strategy"
 )
@@ -27,13 +28,7 @@ func (cl *Client) getRequestStrategyInput(primaryTorrent *Torrent) (input reques
 			input.Capacity = &cap
 		}
 	}
-	if false {
-		if input.Capacity == nil {
-			input.Torrents = []request_strategy.Torrent{primaryTorrent.requestStrategyTorrentInput()}
-			return
-		}
-	}
-	input.Torrents = make([]request_strategy.Torrent, 0, len(cl.torrents))
+	input.Torrents = make(map[metainfo.Hash]request_strategy.Torrent, len(cl.torrents))
 	for _, t := range cl.torrents {
 		if !t.haveInfo() {
 			// This would be removed if metadata is handled here. Determining chunks per piece
@@ -44,7 +39,7 @@ func (cl *Client) getRequestStrategyInput(primaryTorrent *Torrent) (input reques
 		if t.storage.Capacity != primaryTorrent.storage.Capacity {
 			continue
 		}
-		input.Torrents = append(input.Torrents, t.requestStrategyTorrentInput())
+		input.Torrents[t.infoHash] = t.requestStrategyTorrentInput()
 	}
 	return
 }
@@ -132,7 +127,7 @@ type (
 type peerRequests struct {
 	requestIndexes       []RequestIndex
 	peer                 *Peer
-	torrentStrategyInput *request_strategy.Torrent
+	torrentStrategyInput request_strategy.Torrent
 }
 
 func (p *peerRequests) Len() int {
@@ -210,13 +205,7 @@ func (p *Peer) getDesiredRequestState() (desired desiredRequestState) {
 	requestHeap := peerRequests{
 		peer: p,
 	}
-	for i := range input.Torrents {
-		t := &input.Torrents[i]
-		if t.InfoHash == p.t.infoHash {
-			requestHeap.torrentStrategyInput = t
-			break
-		}
-	}
+	requestHeap.torrentStrategyInput = input.Torrents[p.t.infoHash]
 	request_strategy.GetRequestablePieces(
 		input,
 		p.t.cl.pieceRequestOrder[p.t.storage.Capacity],
-- 
2.51.0