internal/pieceordering/pieceordering.go | 8 ++++++-- internal/pieceordering/pieceordering_test.go | 35 +++++++++++++++++++++++++++++++++-- torrent.go | 2 +- diff --git a/internal/pieceordering/pieceordering.go b/internal/pieceordering/pieceordering.go index 169ebbc7ee2ef50356c7d679ff14ffdb5fa0690f..4c4226b0cb79789795d74a62257a7e68b7c4f0c2 100644 --- a/internal/pieceordering/pieceordering.go +++ b/internal/pieceordering/pieceordering.go @@ -89,12 +89,16 @@ delete(me.pieceKeys, piece) } // 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 } return &element{i, i.Value().([]int)} +} + +func (me *Instance) Empty() bool { + return me.sl.Len() == 0 } type Element interface { @@ -120,6 +124,6 @@ e.sl = e.i.Value().([]int) return e } -func (e element) Piece() int { +func (e *element) Piece() int { return e.sl[0] } diff --git a/internal/pieceordering/pieceordering_test.go b/internal/pieceordering/pieceordering_test.go index b2b19e11497bf4f823beec332386aefbe25fdea1..d72b5052d2391c2883239ec676527cbc6ffa69a9 100644 --- a/internal/pieceordering/pieceordering_test.go +++ b/internal/pieceordering/pieceordering_test.go @@ -3,6 +3,9 @@ import ( "sort" "testing" + + "github.com/bradfitz/iter" + "github.com/stretchr/testify/assert" ) func instanceSlice(i *Instance) (sl []int) { @@ -26,7 +29,7 @@ } 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 @@ fatal() } } -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 @@ i.DeletePiece(2) 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 @@ checkOrder(t, i, []int{1}, []int{3, 2}) 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() { + } + } +} diff --git a/torrent.go b/torrent.go index b0c607b05bf2d23aa19c0b8db4cdc8833366f9cc..a9431a38d56a380b91e4777267e8a4fedb051bee 100644 --- a/torrent.go +++ b/torrent.go @@ -738,7 +738,7 @@ return !t.pieceComplete(index) } 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) {