]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Do chunk pooling at Torrent instead of connection level
authorMatt Joiner <anacrolix@gmail.com>
Wed, 5 Oct 2016 04:57:00 +0000 (15:57 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Wed, 5 Oct 2016 04:57:00 +0000 (15:57 +1100)
client.go
connection.go
connection_test.go
torrent.go

index b0df5fa1da88b67501a50627354500b88dc9f2c5..29aed1987396ab7a241596f7fdac91987a29d1a0 100644 (file)
--- a/client.go
+++ b/client.go
@@ -1169,10 +1169,9 @@ func (cl *Client) badPeerIPPort(ip net.IP, port int) bool {
 // 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 @@ 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()
index b25e26629ce345b1cb6b7ce2240019f81c7c2008..742b90af795d13de38fa314d6f8e5173e3c2ef3f 100644 (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 {
index ae6d2348bcc17a170a6f7ad69800e2fd105a320d..52f269b325a33d3d3c5a780c5f6f40283fdacb5e 100644 (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()
index 767f36bff760a2da8f4a486a3e5cd269489027e6..b9ac2f55e32b98d8f094ed6b6aa3e98695d3e87e 100644 (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