github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/db/internal/test_common.go (about) 1 package internal 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "math/rand" 7 "testing" 8 9 "github.com/gnolang/gno/tm2/pkg/db" 10 ) 11 12 const ( 13 strChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" // 62 characters 14 ) 15 16 // RandStr constructs a random alphanumeric string of given length. 17 func RandStr(length int) string { 18 chars := []byte{} 19 MAIN_LOOP: 20 for { 21 //nolint:gosec 22 val := rand.Int63() 23 for i := 0; i < 10; i++ { 24 v := int(val & 0x3f) // rightmost 6 bits 25 if v >= 62 { // only 62 characters in strChars 26 val >>= 6 27 continue 28 } else { 29 chars = append(chars, strChars[v]) 30 if len(chars) == length { 31 break MAIN_LOOP 32 } 33 val >>= 6 34 } 35 } 36 } 37 38 return string(chars) 39 } 40 41 // ---------------------------------------- 42 // MockIterator 43 44 type MockIterator struct{} 45 46 func (MockIterator) Domain() (start []byte, end []byte) { 47 return nil, nil 48 } 49 50 func (MockIterator) Valid() bool { 51 return false 52 } 53 54 func (MockIterator) Next() { 55 } 56 57 func (MockIterator) Key() []byte { 58 return nil 59 } 60 61 func (MockIterator) Value() []byte { 62 return nil 63 } 64 65 func (MockIterator) Close() { 66 } 67 68 func BenchmarkRandomReadsWrites(b *testing.B, db db.DB) { 69 b.Helper() 70 71 b.StopTimer() 72 73 // create dummy data 74 const numItems = int64(1000000) 75 internal := map[int64]int64{} 76 for i := 0; i < int(numItems); i++ { 77 internal[int64(i)] = int64(0) 78 } 79 80 // fmt.Println("ok, starting") 81 b.StartTimer() 82 83 for i := 0; i < b.N; i++ { 84 // Write something 85 { 86 //nolint:gosec 87 idx := int64(rand.Int()) % numItems 88 internal[idx]++ 89 val := internal[idx] 90 idxBytes := int642Bytes(idx) 91 valBytes := int642Bytes(val) 92 // fmt.Printf("Set %X -> %X\n", idxBytes, valBytes) 93 db.Set(idxBytes, valBytes) 94 } 95 96 // Read something 97 { 98 //nolint:gosec 99 idx := int64(rand.Int()) % numItems 100 valExp := internal[idx] 101 idxBytes := int642Bytes(idx) 102 valBytes := db.Get(idxBytes) 103 // fmt.Printf("Get %X -> %X\n", idxBytes, valBytes) 104 if valExp == 0 { 105 if !bytes.Equal(valBytes, nil) { 106 b.Errorf("Expected %v for %v, got %X", nil, idx, valBytes) 107 break 108 } 109 } else { 110 if len(valBytes) != 8 { 111 b.Errorf("Expected length 8 for %v, got %X", idx, valBytes) 112 break 113 } 114 valGot := bytes2Int64(valBytes) 115 if valExp != valGot { 116 b.Errorf("Expected %v for %v, got %v", valExp, idx, valGot) 117 break 118 } 119 } 120 } 121 } 122 } 123 124 func int642Bytes(i int64) []byte { 125 buf := make([]byte, 8) 126 binary.BigEndian.PutUint64(buf, uint64(i)) 127 return buf 128 } 129 130 func bytes2Int64(buf []byte) int64 { 131 return int64(binary.BigEndian.Uint64(buf)) 132 }