Benchmark PieceRequestOrder with varying styles of path hint usage
Add per-piece piece request order path hints
This commit is contained in:
parent
62060fb897
commit
c54dc22592
1
piece.go
1
piece.go
|
@ -8,7 +8,6 @@ import (
|
|||
"github.com/RoaringBitmap/roaring"
|
||||
"github.com/anacrolix/chansync"
|
||||
"github.com/anacrolix/missinggo/v2/bitmap"
|
||||
|
||||
"github.com/anacrolix/torrent/metainfo"
|
||||
pp "github.com/anacrolix/torrent/peer_protocol"
|
||||
"github.com/anacrolix/torrent/storage"
|
||||
|
|
|
@ -21,7 +21,7 @@ func NewPieceOrder() *PieceRequestOrder {
|
|||
type PieceRequestOrder struct {
|
||||
tree *btree.BTree[pieceRequestOrderItem]
|
||||
keys map[PieceRequestOrderKey]PieceRequestOrderState
|
||||
pathHint btree.PathHint
|
||||
PathHint *btree.PathHint
|
||||
}
|
||||
|
||||
type PieceRequestOrderKey struct {
|
||||
|
@ -51,7 +51,7 @@ func (me *PieceRequestOrder) Add(key PieceRequestOrderKey, state PieceRequestOrd
|
|||
if _, ok := me.tree.SetHint(pieceRequestOrderItem{
|
||||
key: key,
|
||||
state: state,
|
||||
}, &me.pathHint); ok {
|
||||
}, me.PathHint); ok {
|
||||
panic("shouldn't already have this")
|
||||
}
|
||||
me.keys[key] = state
|
||||
|
@ -59,7 +59,10 @@ func (me *PieceRequestOrder) Add(key PieceRequestOrderKey, state PieceRequestOrd
|
|||
|
||||
type PieceRequestOrderPathHint = btree.PathHint
|
||||
|
||||
func (me *PieceRequestOrder) Update(key PieceRequestOrderKey, state PieceRequestOrderState) {
|
||||
func (me *PieceRequestOrder) Update(
|
||||
key PieceRequestOrderKey,
|
||||
state PieceRequestOrderState,
|
||||
) {
|
||||
oldState, ok := me.keys[key]
|
||||
if !ok {
|
||||
panic("key should have been added already")
|
||||
|
@ -71,11 +74,11 @@ func (me *PieceRequestOrder) Update(key PieceRequestOrderKey, state PieceRequest
|
|||
key: key,
|
||||
state: oldState,
|
||||
}
|
||||
if _, ok := me.tree.DeleteHint(item, &me.pathHint); !ok {
|
||||
if _, ok := me.tree.DeleteHint(item, me.PathHint); !ok {
|
||||
panic(fmt.Sprintf("%#v", key))
|
||||
}
|
||||
item.state = state
|
||||
if _, ok := me.tree.SetHint(item, &me.pathHint); ok {
|
||||
if _, ok := me.tree.SetHint(item, me.PathHint); ok {
|
||||
panic(key)
|
||||
}
|
||||
me.keys[key] = state
|
||||
|
@ -90,7 +93,7 @@ func (me *PieceRequestOrder) existingItemForKey(key PieceRequestOrderKey) pieceR
|
|||
|
||||
func (me *PieceRequestOrder) Delete(key PieceRequestOrderKey) {
|
||||
item := me.existingItemForKey(key)
|
||||
if _, ok := me.tree.DeleteHint(item, &me.pathHint); !ok {
|
||||
if _, ok := me.tree.DeleteHint(item, me.PathHint); !ok {
|
||||
panic(key)
|
||||
}
|
||||
delete(me.keys, key)
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
package request_strategy
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/bradfitz/iter"
|
||||
)
|
||||
|
||||
func benchmarkPieceRequestOrder(
|
||||
b *testing.B,
|
||||
hintForPiece func(index int) *PieceRequestOrderPathHint,
|
||||
numPieces int,
|
||||
) {
|
||||
b.ResetTimer()
|
||||
b.ReportAllocs()
|
||||
for range iter.N(b.N) {
|
||||
pro := NewPieceOrder()
|
||||
state := PieceRequestOrderState{}
|
||||
doPieces := func(m func(PieceRequestOrderKey)) {
|
||||
for i := range iter.N(numPieces) {
|
||||
key := PieceRequestOrderKey{
|
||||
Index: i,
|
||||
}
|
||||
pro.PathHint = hintForPiece(i)
|
||||
m(key)
|
||||
}
|
||||
}
|
||||
doPieces(func(key PieceRequestOrderKey) {
|
||||
pro.Add(key, state)
|
||||
})
|
||||
state.Availability++
|
||||
doPieces(func(key PieceRequestOrderKey) {
|
||||
pro.Update(key, state)
|
||||
})
|
||||
doPieces(func(key PieceRequestOrderKey) {
|
||||
state.Priority = piecePriority(key.Index / 4)
|
||||
pro.Update(key, state)
|
||||
})
|
||||
// state.Priority = 0
|
||||
state.Availability++
|
||||
doPieces(func(key PieceRequestOrderKey) {
|
||||
pro.Update(key, state)
|
||||
})
|
||||
state.Availability--
|
||||
doPieces(func(key PieceRequestOrderKey) {
|
||||
pro.Update(key, state)
|
||||
})
|
||||
doPieces(pro.Delete)
|
||||
if pro.Len() != 0 {
|
||||
b.FailNow()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkPieceRequestOrder(b *testing.B) {
|
||||
const numPieces = 2000
|
||||
b.Run("NoPathHints", func(b *testing.B) {
|
||||
benchmarkPieceRequestOrder(b, func(int) *PieceRequestOrderPathHint {
|
||||
return nil
|
||||
}, numPieces)
|
||||
})
|
||||
b.Run("SharedPathHint", func(b *testing.B) {
|
||||
var pathHint PieceRequestOrderPathHint
|
||||
benchmarkPieceRequestOrder(b, func(int) *PieceRequestOrderPathHint {
|
||||
return &pathHint
|
||||
}, numPieces)
|
||||
})
|
||||
b.Run("PathHintPerPiece", func(b *testing.B) {
|
||||
pathHints := make([]PieceRequestOrderPathHint, numPieces)
|
||||
benchmarkPieceRequestOrder(b, func(index int) *PieceRequestOrderPathHint {
|
||||
return &pathHints[index]
|
||||
}, numPieces)
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue