]> Sergey Matveev's repositories - btrtrc.git/blob - request-strategy/piece-request-order_test.go
Drop support for go 1.20
[btrtrc.git] / request-strategy / piece-request-order_test.go
1 package requestStrategy
2
3 import (
4         "testing"
5
6         "github.com/bradfitz/iter"
7 )
8
9 func benchmarkPieceRequestOrder[B Btree](
10         b *testing.B,
11         // Initialize the next run, and return a Btree
12         newBtree func() B,
13         // Set any path hinting for the specified piece
14         hintForPiece func(index int),
15         numPieces int,
16 ) {
17         b.ResetTimer()
18         b.ReportAllocs()
19         for range iter.N(b.N) {
20                 pro := NewPieceOrder(newBtree(), numPieces)
21                 state := PieceRequestOrderState{}
22                 doPieces := func(m func(PieceRequestOrderKey)) {
23                         for i := range iter.N(numPieces) {
24                                 key := PieceRequestOrderKey{
25                                         Index: i,
26                                 }
27                                 hintForPiece(i)
28                                 m(key)
29                         }
30                 }
31                 doPieces(func(key PieceRequestOrderKey) {
32                         pro.Add(key, state)
33                 })
34                 state.Availability++
35                 doPieces(func(key PieceRequestOrderKey) {
36                         pro.Update(key, state)
37                 })
38                 pro.tree.Scan(func(item pieceRequestOrderItem) bool {
39                         return true
40                 })
41                 doPieces(func(key PieceRequestOrderKey) {
42                         state.Priority = piecePriority(key.Index / 4)
43                         pro.Update(key, state)
44                 })
45                 pro.tree.Scan(func(item pieceRequestOrderItem) bool {
46                         return item.key.Index < 1000
47                 })
48                 state.Priority = 0
49                 state.Availability++
50                 doPieces(func(key PieceRequestOrderKey) {
51                         pro.Update(key, state)
52                 })
53                 pro.tree.Scan(func(item pieceRequestOrderItem) bool {
54                         return item.key.Index < 1000
55                 })
56                 state.Availability--
57                 doPieces(func(key PieceRequestOrderKey) {
58                         pro.Update(key, state)
59                 })
60                 doPieces(pro.Delete)
61                 if pro.Len() != 0 {
62                         b.FailNow()
63                 }
64         }
65 }
66
67 func zero[T any](t *T) {
68         var zt T
69         *t = zt
70 }
71
72 func BenchmarkPieceRequestOrder(b *testing.B) {
73         const numPieces = 2000
74         b.Run("TidwallBtree", func(b *testing.B) {
75                 b.Run("NoPathHints", func(b *testing.B) {
76                         benchmarkPieceRequestOrder(b, NewTidwallBtree, func(int) {}, numPieces)
77                 })
78                 b.Run("SharedPathHint", func(b *testing.B) {
79                         var pathHint PieceRequestOrderPathHint
80                         var btree *tidwallBtree
81                         benchmarkPieceRequestOrder(
82                                 b, func() *tidwallBtree {
83                                         zero(&pathHint)
84                                         btree = NewTidwallBtree()
85                                         btree.PathHint = &pathHint
86                                         return btree
87                                 }, func(int) {}, numPieces,
88                         )
89                 })
90                 b.Run("PathHintPerPiece", func(b *testing.B) {
91                         pathHints := make([]PieceRequestOrderPathHint, numPieces)
92                         var btree *tidwallBtree
93                         benchmarkPieceRequestOrder(
94                                 b, func() *tidwallBtree {
95                                         btree = NewTidwallBtree()
96                                         return btree
97                                 }, func(index int) {
98                                         btree.PathHint = &pathHints[index]
99                                 }, numPieces,
100                         )
101                 })
102         })
103         b.Run("AjwernerBtree", func(b *testing.B) {
104                 benchmarkPieceRequestOrder(b, NewAjwernerBtree, func(index int) {}, numPieces)
105         })
106 }