github.com/iotexproject/iotex-core@v1.14.1-rc1/db/batch/kv_cache_test.go (about)

     1  // Copyright (c) 2019 IoTeX Foundation
     2  // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability
     3  // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed.
     4  // This source code is governed by Apache License 2.0 that can be found in the LICENSE file.
     5  
     6  package batch
     7  
     8  import (
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/require"
    12  )
    13  
    14  var (
    15  	k1 = &kvCacheKey{"ns", "key"}
    16  	k2 = &kvCacheKey{"nsk", "ey"}
    17  	k3 = &kvCacheKey{"n", "skey"}
    18  
    19  	v1 = []byte("value_1")
    20  	v2 = []byte("value_2")
    21  	v3 = []byte("value_3")
    22  )
    23  
    24  func TestKvCache(t *testing.T) {
    25  	require := require.New(t)
    26  
    27  	c := NewKVCache()
    28  
    29  	// 1. read nonexistent key
    30  	v, err := c.Read(k1)
    31  	require.Equal(err, ErrNotExist)
    32  	require.Nil(v)
    33  
    34  	// 2. write once read many times
    35  	c.Write(k1, v1)
    36  	v, err = c.Read(k1)
    37  	require.NoError(err)
    38  	require.Equal(v, v1)
    39  
    40  	v, err = c.Read(k1)
    41  	require.NoError(err)
    42  	require.Equal(v, v1)
    43  
    44  	// 3. write the same key many times
    45  	err = c.WriteIfNotExist(k1, v1)
    46  	require.Equal(err, ErrAlreadyExist)
    47  
    48  	c.Write(k1, v2)
    49  	v, err = c.Read(k1)
    50  	require.NoError(err)
    51  	require.Equal(v, v2)
    52  
    53  	c.Write(k1, v3)
    54  	v, err = c.Read(k1)
    55  	require.NoError(err)
    56  	require.Equal(v, v3)
    57  
    58  	// 4. delete nonexistent key
    59  	c.Evict(k2)
    60  
    61  	// 5. delete once
    62  	c.Evict(k1)
    63  
    64  	// 6. read deleted key
    65  	v, err = c.Read(k1)
    66  	require.Equal(err, ErrAlreadyDeleted)
    67  	require.Nil(v)
    68  
    69  	// 7. write the same key again after deleted
    70  	c.Write(k1, v1)
    71  	v, err = c.Read(k1)
    72  	require.NoError(err)
    73  	require.Equal(v, v1)
    74  
    75  	// 8. delete the same key many times
    76  	c.Evict(k1)
    77  	c.Evict(k1)
    78  	c.Evict(k1)
    79  
    80  	// 9. write many key-value pairs
    81  	c.Write(k1, v1)
    82  	c.Write(k2, v2)
    83  	c.Write(k3, v3)
    84  
    85  	v, err = c.Read(k1)
    86  	require.NoError(err)
    87  	require.Equal(v, v1)
    88  
    89  	v, err = c.Read(k2)
    90  	require.NoError(err)
    91  	require.Equal(v, v2)
    92  
    93  	v, err = c.Read(k3)
    94  	require.NoError(err)
    95  	require.Equal(v, v3)
    96  }
    97  
    98  func TestKvCacheValue(t *testing.T) {
    99  	require := require.New(t)
   100  
   101  	c := newkvCacheValue([]int{1})
   102  	require.Equal([]int{1}, c.get())
   103  	require.Equal(1, c.len())
   104  
   105  	c.reset()
   106  	require.Equal([]int{0}, c.get())
   107  
   108  	c.append(3)
   109  	require.Equal([]int{0, 3}, c.get())
   110  	require.Equal(0, c.getAt(0))
   111  	require.Equal(3, c.last())
   112  	require.Equal(2, c.len())
   113  	c.pop()
   114  	require.Equal([]int{0}, c.get())
   115  	require.Equal(1, c.len())
   116  }
   117  
   118  func TestWriteIfNotExist(t *testing.T) {
   119  	require := require.New(t)
   120  
   121  	c := NewKVCache()
   122  
   123  	v, err := c.Read(k1)
   124  	require.Equal(err, ErrNotExist)
   125  	require.Nil(v)
   126  
   127  	err = c.WriteIfNotExist(k1, v1)
   128  	require.NoError(err)
   129  
   130  	err = c.WriteIfNotExist(k1, v1)
   131  	require.Equal(err, ErrAlreadyExist)
   132  
   133  	c.Evict(k1)
   134  	err = c.WriteIfNotExist(k1, v1)
   135  	require.NoError(err)
   136  }
   137  
   138  func BenchmarkMapKey_ValueOperate(b *testing.B) {
   139  	keyTags := map[kvCacheKey]*kvCacheValue{}
   140  	keyTags2 := map[kvCacheKey][]int{}
   141  	for i := 0; i < 10000; i++ {
   142  		key := kvCacheKey{
   143  			key1: string(make([]byte, 5)),
   144  			key2: string(make([]byte, 32)),
   145  		}
   146  		keyTags[key] = newkvCacheValue([]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9})
   147  		keyTags2[key] = []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
   148  	}
   149  	b.Run("reset by map key", func(b *testing.B) {
   150  		for i := 0; i < b.N; i++ {
   151  			for k := range keyTags {
   152  				keyTags[k].reset()
   153  			}
   154  		}
   155  	})
   156  	b.Run("reset by map value, 2x faster", func(b *testing.B) {
   157  		for i := 0; i < b.N; i++ {
   158  			for _, v := range keyTags {
   159  				v.reset()
   160  			}
   161  		}
   162  	})
   163  	b.Run("orign map assign", func(b *testing.B) {
   164  		for i := 0; i < b.N; i++ {
   165  			for k := range keyTags2 {
   166  				keyTags2[k] = []int{0}
   167  			}
   168  		}
   169  	})
   170  }