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  }