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 }