client.go | 10 +++++----- connection.go | 9 ++------- connection_test.go | 2 +- torrent.go | 10 ++++++++++ diff --git a/client.go b/client.go index b0df5fa1da88b67501a50627354500b88dc9f2c5..29aed1987396ab7a241596f7fdac91987a29d1a0 100644 --- a/client.go +++ b/client.go @@ -1169,10 +1169,9 @@ // Return a Torrent ready for insertion into a Client. func (cl *Client) newTorrent(ih metainfo.Hash) (t *Torrent) { t = &Torrent{ - cl: cl, - infoHash: ih, - chunkSize: defaultChunkSize, - peers: make(map[peersKey]Peer), + cl: cl, + infoHash: ih, + peers: make(map[peersKey]Peer), halfOpen: make(map[string]struct{}), pieceStateChanges: pubsub.NewPubSub(), @@ -1180,6 +1179,7 @@ storageOpener: cl.defaultStorage, maxEstablishedConns: defaultEstablishedConnsPerTorrent, } + t.setChunkSize(defaultChunkSize) return } @@ -1228,7 +1228,7 @@ } cl.mu.Lock() defer cl.mu.Unlock() if spec.ChunkSize != 0 { - t.chunkSize = pp.Integer(spec.ChunkSize) + t.setChunkSize(pp.Integer(spec.ChunkSize)) } t.addTrackers(spec.Trackers) t.maybeNewConns() diff --git a/connection.go b/connection.go index b25e26629ce345b1cb6b7ce2240019f81c7c2008..742b90af795d13de38fa314d6f8e5173e3c2ef3f 100644 --- a/connection.go +++ b/connection.go @@ -698,16 +698,11 @@ // and exit. Returning will end the connection. func (c *connection) mainReadLoop() error { t := c.t cl := t.cl - pool := &sync.Pool{ - New: func() interface{} { - return make([]byte, t.chunkSize) - }, - } decoder := pp.Decoder{ R: bufio.NewReader(c.rw), MaxLength: 256 * 1024, - Pool: pool, + Pool: t.chunkPool, } for { cl.mu.Unlock() @@ -782,7 +777,7 @@ err = c.peerSentHaveNone() case pp.Piece: cl.downloadedChunk(t, c, &msg) if len(msg.Piece) == int(t.chunkSize) { - pool.Put(msg.Piece) + t.chunkPool.Put(msg.Piece) } case pp.Extended: switch msg.ExtendedID { diff --git a/connection_test.go b/connection_test.go index ae6d2348bcc17a170a6f7ad69800e2fd105a320d..52f269b325a33d3d3c5a780c5f6f40283fdacb5e 100644 --- a/connection_test.go +++ b/connection_test.go @@ -144,10 +144,10 @@ Pieces: make([]byte, 20), Length: 1 << 20, PieceLength: 1 << 20, }, - chunkSize: defaultChunkSize, storage: &storage.Torrent{ts}, pieceStateChanges: pubsub.NewPubSub(), } + t.setChunkSize(defaultChunkSize) t.makePieces() t.pendingPieces.Add(0) r, w := io.Pipe() diff --git a/torrent.go b/torrent.go index 767f36bff760a2da8f4a486a3e5cd269489027e6..b9ac2f55e32b98d8f094ed6b6aa3e98695d3e87e 100644 --- a/torrent.go +++ b/torrent.go @@ -52,6 +52,7 @@ pieceStateChanges *pubsub.PubSub // The size of chunks to request from peers over the wire. This is // normally 16KiB by convention these days. chunkSize pp.Integer + chunkPool *sync.Pool // Total length of the torrent in bytes. Stored because it's not O(1) to // get this from the info dict. length int64 @@ -113,6 +114,15 @@ // different pieces. connPieceInclinationPool sync.Pool // Torrent-level statistics. stats TorrentStats +} + +func (t *Torrent) setChunkSize(size pp.Integer) { + t.chunkSize = size + t.chunkPool = &sync.Pool{ + New: func() interface{} { + return make([]byte, size) + }, + } } func (t *Torrent) setDisplayName(dn string) {