Do chunk pooling at Torrent instead of connection level

This commit is contained in:
Matt Joiner 2016-10-05 15:57:00 +11:00
parent d72d93bba7
commit de761fb506
4 changed files with 18 additions and 13 deletions

View File

@ -1171,7 +1171,6 @@ func (cl *Client) newTorrent(ih metainfo.Hash) (t *Torrent) {
t = &Torrent{
cl: cl,
infoHash: ih,
chunkSize: defaultChunkSize,
peers: make(map[peersKey]Peer),
halfOpen: make(map[string]struct{}),
@ -1180,6 +1179,7 @@ func (cl *Client) newTorrent(ih metainfo.Hash) (t *Torrent) {
storageOpener: cl.defaultStorage,
maxEstablishedConns: defaultEstablishedConnsPerTorrent,
}
t.setChunkSize(defaultChunkSize)
return
}
@ -1228,7 +1228,7 @@ func (cl *Client) AddTorrentSpec(spec *TorrentSpec) (t *Torrent, new bool, err e
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()

View File

@ -698,16 +698,11 @@ func (c *connection) lastHelpful() (ret time.Time) {
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 @@ func (c *connection) mainReadLoop() error {
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 {

View File

@ -144,10 +144,10 @@ func BenchmarkConnectionMainReadLoop(b *testing.B) {
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()

View File

@ -52,6 +52,7 @@ type Torrent struct {
// 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
@ -115,6 +116,15 @@ type Torrent struct {
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) {
if t.haveInfo() {
return