]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Avoid frequent allocation of piece request order iterator
authorMatt Joiner <anacrolix@gmail.com>
Sun, 20 Sep 2015 01:29:52 +0000 (11:29 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Sun, 20 Sep 2015 01:29:52 +0000 (11:29 +1000)
internal/pieceordering/pieceordering.go
internal/pieceordering/pieceordering_test.go
torrent.go

index 169ebbc7ee2ef50356c7d679ff14ffdb5fa0690f..4c4226b0cb79789795d74a62257a7e68b7c4f0c2 100644 (file)
@@ -89,7 +89,7 @@ func (me *Instance) DeletePiece(piece int) {
 }
 
 // Returns the piece with the lowest key.
-func (me Instance) First() Element {
+func (me *Instance) First() Element {
        i := me.sl.SeekToFirst()
        if i == nil {
                return nil
@@ -97,6 +97,10 @@ func (me Instance) First() Element {
        return &element{i, i.Value().([]int)}
 }
 
+func (me *Instance) Empty() bool {
+       return me.sl.Len() == 0
+}
+
 type Element interface {
        Piece() int
        Next() Element
@@ -120,6 +124,6 @@ func (e *element) Next() Element {
        return e
 }
 
-func (e element) Piece() int {
+func (e *element) Piece() int {
        return e.sl[0]
 }
index b2b19e11497bf4f823beec332386aefbe25fdea1..d72b5052d2391c2883239ec676527cbc6ffa69a9 100644 (file)
@@ -3,6 +3,9 @@ package pieceordering
 import (
        "sort"
        "testing"
+
+       "github.com/bradfitz/iter"
+       "github.com/stretchr/testify/assert"
 )
 
 func instanceSlice(i *Instance) (sl []int) {
@@ -26,7 +29,7 @@ func sameContents(a, b []int) bool {
        return true
 }
 
-func checkOrder(t *testing.T, i *Instance, ppp ...[]int) {
+func checkOrder(t testing.TB, i *Instance, ppp ...[]int) {
        fatal := func() {
                t.Fatalf("have %v, expected %v", instanceSlice(i), ppp)
        }
@@ -46,9 +49,11 @@ func checkOrder(t *testing.T, i *Instance, ppp ...[]int) {
        }
 }
 
-func TestPieceOrdering(t *testing.T) {
+func testPieceOrdering(t testing.TB) {
        i := New()
+       assert.True(t, i.Empty())
        i.SetPiece(0, 1)
+       assert.False(t, i.Empty())
        i.SetPiece(1, 0)
        checkOrder(t, i, []int{1, 0})
        i.SetPiece(1, 2)
@@ -59,8 +64,10 @@ func TestPieceOrdering(t *testing.T) {
        i.DeletePiece(1)
        checkOrder(t, i, []int{0})
        i.DeletePiece(0)
+       assert.True(t, i.Empty())
        checkOrder(t, i, nil)
        i.SetPiece(2, 1)
+       assert.False(t, i.Empty())
        i.SetPiece(1, 1)
        i.SetPiece(3, 1)
        checkOrder(t, i, []int{3, 1, 2})
@@ -70,9 +77,33 @@ func TestPieceOrdering(t *testing.T) {
        i.DeletePiece(2)
        i.DeletePiece(3)
        i.DeletePiece(1)
+       assert.True(t, i.Empty())
        checkOrder(t, i, nil)
+       // Deleting pieces that aren't present.
        i.DeletePiece(2)
        i.DeletePiece(3)
        i.DeletePiece(1)
+       assert.True(t, i.Empty())
        checkOrder(t, i, nil)
 }
+
+func TestPieceOrdering(t *testing.T) {
+       testPieceOrdering(t)
+}
+
+func BenchmarkPieceOrdering(b *testing.B) {
+       for range iter.N(b.N) {
+               testPieceOrdering(b)
+       }
+}
+
+func BenchmarkIteration(b *testing.B) {
+       for range iter.N(b.N) {
+               i := New()
+               for p := range iter.N(500) {
+                       i.SetPiece(p, p)
+               }
+               for e := i.First(); e != nil; e = e.Next() {
+               }
+       }
+}
index b0c607b05bf2d23aa19c0b8db4cdc8833366f9cc..a9431a38d56a380b91e4777267e8a4fedb051bee 100644 (file)
@@ -738,7 +738,7 @@ func (t *torrent) wantPiece(index int) bool {
 }
 
 func (t *torrent) connHasWantedPieces(c *connection) bool {
-       return c.pieceRequestOrder != nil && c.pieceRequestOrder.First() != nil
+       return c.pieceRequestOrder != nil && !c.pieceRequestOrder.Empty()
 }
 
 func (t *torrent) extentPieces(off, _len int64) (pieces []int) {