2021-12-17 18:25:38 +08:00
|
|
|
package request_strategy
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/bradfitz/iter"
|
|
|
|
)
|
|
|
|
|
2021-12-18 13:07:44 +08:00
|
|
|
func benchmarkPieceRequestOrder[B Btree](
|
2021-12-17 18:25:38 +08:00
|
|
|
b *testing.B,
|
2021-12-18 13:07:44 +08:00
|
|
|
// Initialize the next run, and return a Btree
|
|
|
|
newBtree func() B,
|
|
|
|
// Set any path hinting for the specified piece
|
|
|
|
hintForPiece func(index int),
|
2021-12-17 18:25:38 +08:00
|
|
|
numPieces int,
|
|
|
|
) {
|
|
|
|
b.ResetTimer()
|
|
|
|
b.ReportAllocs()
|
|
|
|
for range iter.N(b.N) {
|
2021-12-18 13:07:44 +08:00
|
|
|
pro := NewPieceOrder(newBtree(), numPieces)
|
2021-12-17 18:25:38 +08:00
|
|
|
state := PieceRequestOrderState{}
|
|
|
|
doPieces := func(m func(PieceRequestOrderKey)) {
|
|
|
|
for i := range iter.N(numPieces) {
|
|
|
|
key := PieceRequestOrderKey{
|
|
|
|
Index: i,
|
|
|
|
}
|
2021-12-18 13:07:44 +08:00
|
|
|
hintForPiece(i)
|
2021-12-17 18:25:38 +08:00
|
|
|
m(key)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
doPieces(func(key PieceRequestOrderKey) {
|
|
|
|
pro.Add(key, state)
|
|
|
|
})
|
|
|
|
state.Availability++
|
|
|
|
doPieces(func(key PieceRequestOrderKey) {
|
|
|
|
pro.Update(key, state)
|
|
|
|
})
|
2021-12-18 13:07:44 +08:00
|
|
|
pro.tree.Scan(func(item pieceRequestOrderItem) bool {
|
|
|
|
return true
|
|
|
|
})
|
2021-12-17 18:25:38 +08:00
|
|
|
doPieces(func(key PieceRequestOrderKey) {
|
|
|
|
state.Priority = piecePriority(key.Index / 4)
|
|
|
|
pro.Update(key, state)
|
|
|
|
})
|
2021-12-18 13:07:44 +08:00
|
|
|
pro.tree.Scan(func(item pieceRequestOrderItem) bool {
|
|
|
|
return item.key.Index < 1000
|
|
|
|
})
|
|
|
|
state.Priority = 0
|
2021-12-17 18:25:38 +08:00
|
|
|
state.Availability++
|
|
|
|
doPieces(func(key PieceRequestOrderKey) {
|
|
|
|
pro.Update(key, state)
|
|
|
|
})
|
2021-12-18 13:07:44 +08:00
|
|
|
pro.tree.Scan(func(item pieceRequestOrderItem) bool {
|
|
|
|
return item.key.Index < 1000
|
|
|
|
})
|
2021-12-17 18:25:38 +08:00
|
|
|
state.Availability--
|
|
|
|
doPieces(func(key PieceRequestOrderKey) {
|
|
|
|
pro.Update(key, state)
|
|
|
|
})
|
|
|
|
doPieces(pro.Delete)
|
|
|
|
if pro.Len() != 0 {
|
|
|
|
b.FailNow()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-18 13:07:44 +08:00
|
|
|
func zero[T any](t *T) {
|
|
|
|
var zt T
|
|
|
|
*t = zt
|
|
|
|
}
|
|
|
|
|
2021-12-17 18:25:38 +08:00
|
|
|
func BenchmarkPieceRequestOrder(b *testing.B) {
|
|
|
|
const numPieces = 2000
|
2021-12-18 13:07:44 +08:00
|
|
|
b.Run("TidwallBtree", func(b *testing.B) {
|
|
|
|
b.Run("NoPathHints", func(b *testing.B) {
|
|
|
|
benchmarkPieceRequestOrder(b, NewTidwallBtree, func(int) {}, numPieces)
|
|
|
|
})
|
|
|
|
b.Run("SharedPathHint", func(b *testing.B) {
|
|
|
|
var pathHint PieceRequestOrderPathHint
|
|
|
|
var btree *tidwallBtree
|
|
|
|
benchmarkPieceRequestOrder(
|
|
|
|
b, func() *tidwallBtree {
|
|
|
|
zero(&pathHint)
|
|
|
|
btree = NewTidwallBtree()
|
|
|
|
btree.PathHint = &pathHint
|
|
|
|
return btree
|
|
|
|
}, func(int) {}, numPieces,
|
|
|
|
)
|
|
|
|
})
|
|
|
|
b.Run("PathHintPerPiece", func(b *testing.B) {
|
|
|
|
pathHints := make([]PieceRequestOrderPathHint, numPieces)
|
|
|
|
var btree *tidwallBtree
|
|
|
|
benchmarkPieceRequestOrder(
|
|
|
|
b, func() *tidwallBtree {
|
|
|
|
btree = NewTidwallBtree()
|
|
|
|
return btree
|
|
|
|
}, func(index int) {
|
|
|
|
btree.PathHint = &pathHints[index]
|
|
|
|
}, numPieces,
|
|
|
|
)
|
|
|
|
})
|
2021-12-17 18:25:38 +08:00
|
|
|
})
|
2021-12-18 13:07:44 +08:00
|
|
|
b.Run("AjwernerBtree", func(b *testing.B) {
|
|
|
|
benchmarkPieceRequestOrder(b, NewAjwernerBtree, func(index int) {}, numPieces)
|
2021-12-17 18:25:38 +08:00
|
|
|
})
|
|
|
|
}
|