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