]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Add a benchmark for readMainLoop piece decoding
authorMatt Joiner <anacrolix@gmail.com>
Sun, 11 Sep 2016 05:43:57 +0000 (15:43 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Sun, 11 Sep 2016 05:43:57 +0000 (15:43 +1000)
connection_test.go

index 2f6bed4e2b09bcbfad4a3084101d299a4badd02e..ae6d2348bcc17a170a6f7ad69800e2fd105a320d 100644 (file)
@@ -5,12 +5,19 @@ import (
        "io"
        "io/ioutil"
        "net"
+       "sync"
        "testing"
        "time"
 
        "github.com/anacrolix/missinggo/bitmap"
+       "github.com/anacrolix/missinggo/pubsub"
+       "github.com/bradfitz/iter"
        "github.com/stretchr/testify/assert"
        "github.com/stretchr/testify/require"
+
+       "github.com/anacrolix/torrent/metainfo"
+       "github.com/anacrolix/torrent/peer_protocol"
+       "github.com/anacrolix/torrent/storage"
 )
 
 func TestCancelRequestOptimized(t *testing.T) {
@@ -92,3 +99,92 @@ func TestSendBitfieldThenHave(t *testing.T) {
        // arrive in the following Have message.
        require.EqualValues(t, "\x00\x00\x00\x02\x05@\x00\x00\x00\x05\x04\x00\x00\x00\x02", string(b))
 }
+
+type torrentStorage struct {
+       writeSem sync.Mutex
+}
+
+func (me *torrentStorage) Close() error { return nil }
+
+func (me *torrentStorage) Piece(mp metainfo.Piece) storage.PieceImpl {
+       return me
+}
+
+func (me *torrentStorage) GetIsComplete() bool {
+       return false
+}
+
+func (me *torrentStorage) MarkComplete() error {
+       return nil
+}
+
+func (me *torrentStorage) MarkNotComplete() error {
+       return nil
+}
+
+func (me *torrentStorage) ReadAt([]byte, int64) (int, error) {
+       panic("shouldn't be called")
+}
+
+func (me *torrentStorage) WriteAt(b []byte, _ int64) (int, error) {
+       if len(b) != defaultChunkSize {
+               panic(len(b))
+       }
+       me.writeSem.Unlock()
+       return len(b), nil
+}
+
+func BenchmarkConnectionMainReadLoop(b *testing.B) {
+       cl := &Client{}
+       ts := &torrentStorage{}
+       t := &Torrent{
+               cl: cl,
+               info: &metainfo.Info{
+                       Pieces:      make([]byte, 20),
+                       Length:      1 << 20,
+                       PieceLength: 1 << 20,
+               },
+               chunkSize:         defaultChunkSize,
+               storage:           &storage.Torrent{ts},
+               pieceStateChanges: pubsub.NewPubSub(),
+       }
+       t.makePieces()
+       t.pendingPieces.Add(0)
+       r, w := io.Pipe()
+       cn := &connection{
+               t: t,
+               rw: struct {
+                       io.Reader
+                       io.Writer
+               }{r, nil},
+       }
+       mrlErr := make(chan error)
+       cl.mu.Lock()
+       go func() {
+               err := cn.mainReadLoop()
+               if err != nil {
+                       mrlErr <- err
+               }
+               close(mrlErr)
+       }()
+       msg := peer_protocol.Message{
+               Type:  peer_protocol.Piece,
+               Piece: make([]byte, defaultChunkSize),
+       }
+       wb, err := msg.MarshalBinary()
+       require.NoError(b, err)
+       b.SetBytes(int64(len(msg.Piece)))
+       ts.writeSem.Lock()
+       for range iter.N(b.N) {
+               cl.mu.Lock()
+               t.pieces[0].DirtyChunks.Clear()
+               cl.mu.Unlock()
+               n, err := w.Write(wb)
+               require.NoError(b, err)
+               require.EqualValues(b, len(wb), n)
+               ts.writeSem.Lock()
+       }
+       w.Close()
+       require.NoError(b, <-mrlErr)
+       require.EqualValues(b, b.N, cn.UsefulChunksReceived)
+}