github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/iavl/testutils_test.go (about)

     1  package iavl
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	mrand "math/rand"
     7  	"runtime"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/require"
    11  
    12  	"github.com/gnolang/gno/tm2/pkg/amino"
    13  	"github.com/gnolang/gno/tm2/pkg/db"
    14  	_ "github.com/gnolang/gno/tm2/pkg/db/memdb"
    15  	"github.com/gnolang/gno/tm2/pkg/random"
    16  )
    17  
    18  func randstr(length int) string {
    19  	return random.RandStr(length)
    20  }
    21  
    22  func i2b(i int) []byte {
    23  	buf := new(bytes.Buffer)
    24  	amino.EncodeInt32(buf, int32(i))
    25  	return buf.Bytes()
    26  }
    27  
    28  func b2i(bz []byte) int {
    29  	i, _, _ := amino.DecodeInt32(bz)
    30  	return int(i)
    31  }
    32  
    33  // Convenience for a new node
    34  func N(l, r interface{}) *Node {
    35  	var left, right *Node
    36  	if _, ok := l.(*Node); ok {
    37  		left = l.(*Node)
    38  	} else {
    39  		left = NewNode(i2b(l.(int)), nil, 0)
    40  	}
    41  	if _, ok := r.(*Node); ok {
    42  		right = r.(*Node)
    43  	} else {
    44  		right = NewNode(i2b(r.(int)), nil, 0)
    45  	}
    46  
    47  	n := &Node{
    48  		key:       right.lmd(nil).key,
    49  		value:     nil,
    50  		leftNode:  left,
    51  		rightNode: right,
    52  	}
    53  	n.calcHeightAndSize(nil)
    54  	return n
    55  }
    56  
    57  // Setup a deep node
    58  func T(n *Node) *MutableTree {
    59  	d, err := db.NewDB("test", db.MemDBBackend, "")
    60  	if err != nil {
    61  		panic(err)
    62  	}
    63  
    64  	t := NewMutableTree(d, 0)
    65  
    66  	n.hashWithCount()
    67  	t.root = n
    68  	return t
    69  }
    70  
    71  // Convenience for simple printing of keys & tree structure
    72  func P(n *Node) string {
    73  	if n.height == 0 {
    74  		return fmt.Sprintf("%v", b2i(n.key))
    75  	}
    76  	return fmt.Sprintf("(%v %v)", P(n.leftNode), P(n.rightNode))
    77  }
    78  
    79  func randBytes(length int) []byte {
    80  	key := make([]byte, length)
    81  	// math.rand.Read always returns err=nil
    82  	// we do not need cryptographic randomness for this test:
    83  	mrand.Read(key)
    84  	return key
    85  }
    86  
    87  type traverser struct {
    88  	first string
    89  	last  string
    90  	count int
    91  }
    92  
    93  func (t *traverser) view(key, value []byte) bool {
    94  	if t.first == "" {
    95  		t.first = string(key)
    96  	}
    97  	t.last = string(key)
    98  	t.count++
    99  	return false
   100  }
   101  
   102  func expectTraverse(t *testing.T, trav traverser, start, end string, count int) {
   103  	t.Helper()
   104  
   105  	if trav.first != start {
   106  		t.Error("Bad start", start, trav.first)
   107  	}
   108  	if trav.last != end {
   109  		t.Error("Bad end", end, trav.last)
   110  	}
   111  	if trav.count != count {
   112  		t.Error("Bad count", count, trav.count)
   113  	}
   114  }
   115  
   116  func BenchmarkImmutableAvlTreeMemDB(b *testing.B) {
   117  	if testing.Short() {
   118  		b.Skip("skipping testing in short mode")
   119  	}
   120  
   121  	db, err := db.NewDB("test", db.MemDBBackend, "")
   122  	require.NoError(b, err)
   123  
   124  	b.ResetTimer()
   125  
   126  	benchmarkImmutableAvlTreeWithDB(b, db)
   127  }
   128  
   129  func benchmarkImmutableAvlTreeWithDB(b *testing.B, db db.DB) {
   130  	b.Helper()
   131  
   132  	defer db.Close()
   133  
   134  	b.StopTimer()
   135  
   136  	t := NewMutableTree(db, 100000)
   137  	value := []byte{}
   138  	for i := 0; i < 1000000; i++ {
   139  		t.Set(i2b(int(random.RandInt31())), value)
   140  		if i > 990000 && i%1000 == 999 {
   141  			t.SaveVersion()
   142  		}
   143  	}
   144  	b.ReportAllocs()
   145  	t.SaveVersion()
   146  
   147  	runtime.GC()
   148  
   149  	b.StartTimer()
   150  	for i := 0; i < b.N; i++ {
   151  		ri := i2b(int(random.RandInt31()))
   152  		t.Set(ri, value)
   153  		t.Remove(ri)
   154  		if i%100 == 99 {
   155  			t.SaveVersion()
   156  		}
   157  	}
   158  }