github.com/matrixorigin/matrixone@v0.7.0/pkg/lockservice/storage_test.go (about) 1 // Copyright 2022 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package lockservice 16 17 import ( 18 "encoding/binary" 19 "math/rand" 20 "testing" 21 22 "github.com/stretchr/testify/assert" 23 ) 24 25 var ( 26 storages = map[string]func() LockStorage{ 27 "btree": newBtreeBasedStorage, 28 } 29 ) 30 31 func TestAdd(t *testing.T) { 32 for name, factory := range storages { 33 t.Run(name, func(t *testing.T) { 34 s := factory() 35 36 k1 := []byte("k1") 37 s.Add(k1, Lock{txnID: k1}) 38 assert.Equal(t, 1, s.Len()) 39 40 v, ok := s.Get(k1) 41 assert.True(t, ok) 42 assert.Equal(t, k1, v.txnID) 43 }) 44 } 45 } 46 47 func TestDelete(t *testing.T) { 48 for name, factory := range storages { 49 t.Run(name, func(t *testing.T) { 50 s := factory() 51 52 k1 := []byte("k1") 53 k2 := []byte("k2") 54 s.Add(k1, Lock{}) 55 s.Add(k2, Lock{}) 56 57 s.Delete(k1) 58 assert.Equal(t, 1, s.Len()) 59 v, ok := s.Get(k1) 60 assert.False(t, ok) 61 assert.Empty(t, v) 62 63 s.Delete(k2) 64 assert.Equal(t, 0, s.Len()) 65 v, ok = s.Get(k2) 66 assert.False(t, ok) 67 assert.Empty(t, v) 68 }) 69 } 70 } 71 72 func TestSeek(t *testing.T) { 73 for name, factory := range storages { 74 t.Run(name, func(t *testing.T) { 75 s := factory() 76 77 k1 := []byte("k1") 78 k2 := []byte("k2") 79 k3 := []byte("k3") 80 81 checkSeek(t, s, k1, nil, nil) 82 83 s.Add(k1, Lock{txnID: k1}) 84 checkSeek(t, s, k1, k1, k1) 85 checkSeek(t, s, k2, nil, nil) 86 checkSeek(t, s, k3, nil, nil) 87 88 s.Add(k2, Lock{txnID: k2}) 89 checkSeek(t, s, k1, k1, k1) 90 checkSeek(t, s, k2, k2, k2) 91 checkSeek(t, s, k3, nil, nil) 92 93 s.Add(k3, Lock{txnID: k3}) 94 checkSeek(t, s, k1, k1, k1) 95 checkSeek(t, s, k2, k2, k2) 96 checkSeek(t, s, k3, k3, k3) 97 }) 98 } 99 } 100 101 func BenchmarkAdd(b *testing.B) { 102 for name, factory := range storages { 103 b.Run(name, func(b *testing.B) { 104 s := factory() 105 keys := make([][]byte, b.N) 106 for i := 0; i < b.N; i++ { 107 keys[i] = make([]byte, 4) 108 binary.BigEndian.PutUint32(keys[i], rand.Uint32()) 109 } 110 111 b.ResetTimer() 112 for i := 0; i < b.N; i++ { 113 s.Add(keys[i], Lock{txnID: keys[i]}) 114 } 115 }) 116 } 117 } 118 119 func BenchmarkSeek(b *testing.B) { 120 for name, factory := range storages { 121 b.Run(name, func(b *testing.B) { 122 s := factory() 123 keys := make([][]byte, b.N) 124 for i := 0; i < b.N; i++ { 125 keys[i] = make([]byte, 4) 126 binary.BigEndian.PutUint32(keys[i], rand.Uint32()) 127 } 128 129 b.ResetTimer() 130 for i := 0; i < b.N; i++ { 131 s.Seek(keys[i]) 132 } 133 }) 134 } 135 } 136 137 func BenchmarkDelete(b *testing.B) { 138 for name, factory := range storages { 139 b.Run(name, func(b *testing.B) { 140 s := factory() 141 keys := make([][]byte, b.N) 142 for i := 0; i < b.N; i++ { 143 keys[i] = make([]byte, 4) 144 binary.BigEndian.PutUint32(keys[i], rand.Uint32()) 145 s.Add(keys[i], Lock{txnID: keys[i]}) 146 } 147 148 b.ResetTimer() 149 for i := 0; i < b.N; i++ { 150 s.Delete(keys[i]) 151 } 152 }) 153 } 154 } 155 156 func checkSeek(t *testing.T, s LockStorage, key []byte, expectKey, expectValue []byte) { 157 k, v, ok := s.Seek(key) 158 if len(expectKey) == 0 { 159 assert.Empty(t, k) 160 assert.Empty(t, v) 161 assert.False(t, ok) 162 return 163 } 164 assert.Equal(t, expectKey, k) 165 assert.Equal(t, expectValue, v.txnID) 166 assert.True(t, ok) 167 }