Avoid frequent allocation of piece request order iterator

This commit is contained in:
Matt Joiner 2015-09-20 11:29:52 +10:00
parent 31ce250a6b
commit f9ed9c4c04
3 changed files with 40 additions and 5 deletions

View 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]
}

View 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() {
}
}
}

View 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) {