github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/soliton/kvcache/simple_lru_test.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 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 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package ekvcache 15 16 import ( 17 "fmt" 18 "reflect" 19 "testing" 20 21 . "github.com/whtcorpsinc/check" 22 "github.com/whtcorpsinc/milevadb/soliton/memory" 23 ) 24 25 func TestT(t *testing.T) { 26 CustomVerboseFlag = true 27 TestingT(t) 28 } 29 30 var _ = Suite(&testLRUCacheSuite{}) 31 32 type testLRUCacheSuite struct { 33 } 34 35 type mockCacheKey struct { 36 hash []byte 37 key int64 38 } 39 40 func (mk *mockCacheKey) Hash() []byte { 41 if mk.hash != nil { 42 return mk.hash 43 } 44 mk.hash = make([]byte, 8) 45 for i := uint(0); i < 8; i++ { 46 mk.hash[i] = byte((mk.key >> ((i - 1) * 8)) & 0xff) 47 } 48 return mk.hash 49 } 50 51 func newMockHashKey(key int64) *mockCacheKey { 52 return &mockCacheKey{ 53 key: key, 54 } 55 } 56 57 func (s *testLRUCacheSuite) TestPut(c *C) { 58 maxMem, err := memory.MemTotal() 59 c.Assert(err, IsNil) 60 61 lru := NewSimpleLRUCache(3, 0, maxMem) 62 c.Assert(lru.capacity, Equals, uint(3)) 63 64 keys := make([]*mockCacheKey, 5) 65 vals := make([]int64, 5) 66 67 for i := 0; i < 5; i++ { 68 keys[i] = newMockHashKey(int64(i)) 69 vals[i] = int64(i) 70 lru.Put(keys[i], vals[i]) 71 } 72 c.Assert(lru.size, Equals, lru.capacity) 73 c.Assert(lru.size, Equals, uint(3)) 74 75 // test for non-existent elements 76 for i := 0; i < 2; i++ { 77 element, exists := lru.elements[string(keys[i].Hash())] 78 c.Assert(exists, IsFalse) 79 c.Assert(element, IsNil) 80 } 81 82 // test for existent elements 83 root := lru.cache.Front() 84 c.Assert(root, NotNil) 85 for i := 4; i >= 2; i-- { 86 entry, ok := root.Value.(*cacheEntry) 87 c.Assert(ok, IsTrue) 88 c.Assert(entry, NotNil) 89 90 // test key 91 key := entry.key 92 c.Assert(key, NotNil) 93 c.Assert(key, Equals, keys[i]) 94 95 element, exists := lru.elements[string(keys[i].Hash())] 96 c.Assert(exists, IsTrue) 97 c.Assert(element, NotNil) 98 c.Assert(element, Equals, root) 99 100 // test value 101 value, ok := entry.value.(int64) 102 c.Assert(ok, IsTrue) 103 c.Assert(value, Equals, vals[i]) 104 105 root = root.Next() 106 } 107 // test for end of double-linked list 108 c.Assert(root, IsNil) 109 } 110 111 func (s *testLRUCacheSuite) TestZeroQuota(c *C) { 112 lru := NewSimpleLRUCache(100, 0, 0) 113 c.Assert(lru.capacity, Equals, uint(100)) 114 115 keys := make([]*mockCacheKey, 100) 116 vals := make([]int64, 100) 117 118 for i := 0; i < 100; i++ { 119 keys[i] = newMockHashKey(int64(i)) 120 vals[i] = int64(i) 121 lru.Put(keys[i], vals[i]) 122 } 123 c.Assert(lru.size, Equals, lru.capacity) 124 c.Assert(lru.size, Equals, uint(100)) 125 } 126 127 func (s *testLRUCacheSuite) TestOOMGuard(c *C) { 128 maxMem, err := memory.MemTotal() 129 c.Assert(err, IsNil) 130 131 lru := NewSimpleLRUCache(3, 1.0, maxMem) 132 c.Assert(lru.capacity, Equals, uint(3)) 133 134 keys := make([]*mockCacheKey, 5) 135 vals := make([]int64, 5) 136 137 for i := 0; i < 5; i++ { 138 keys[i] = newMockHashKey(int64(i)) 139 vals[i] = int64(i) 140 lru.Put(keys[i], vals[i]) 141 } 142 c.Assert(lru.size, Equals, uint(0)) 143 144 // test for non-existent elements 145 for i := 0; i < 5; i++ { 146 element, exists := lru.elements[string(keys[i].Hash())] 147 c.Assert(exists, IsFalse) 148 c.Assert(element, IsNil) 149 } 150 } 151 152 func (s *testLRUCacheSuite) TestGet(c *C) { 153 maxMem, err := memory.MemTotal() 154 c.Assert(err, IsNil) 155 156 lru := NewSimpleLRUCache(3, 0, maxMem) 157 158 keys := make([]*mockCacheKey, 5) 159 vals := make([]int64, 5) 160 161 for i := 0; i < 5; i++ { 162 keys[i] = newMockHashKey(int64(i)) 163 vals[i] = int64(i) 164 lru.Put(keys[i], vals[i]) 165 } 166 167 // test for non-existent elements 168 for i := 0; i < 2; i++ { 169 value, exists := lru.Get(keys[i]) 170 c.Assert(exists, IsFalse) 171 c.Assert(value, IsNil) 172 } 173 174 for i := 2; i < 5; i++ { 175 value, exists := lru.Get(keys[i]) 176 c.Assert(exists, IsTrue) 177 c.Assert(value, NotNil) 178 c.Assert(value, Equals, vals[i]) 179 c.Assert(lru.size, Equals, uint(3)) 180 c.Assert(lru.capacity, Equals, uint(3)) 181 182 root := lru.cache.Front() 183 c.Assert(root, NotNil) 184 185 entry, ok := root.Value.(*cacheEntry) 186 c.Assert(ok, IsTrue) 187 c.Assert(entry.key, Equals, keys[i]) 188 189 value, ok = entry.value.(int64) 190 c.Assert(ok, IsTrue) 191 c.Assert(value, Equals, vals[i]) 192 } 193 } 194 195 func (s *testLRUCacheSuite) TestDelete(c *C) { 196 maxMem, err := memory.MemTotal() 197 c.Assert(err, IsNil) 198 199 lru := NewSimpleLRUCache(3, 0, maxMem) 200 201 keys := make([]*mockCacheKey, 3) 202 vals := make([]int64, 3) 203 204 for i := 0; i < 3; i++ { 205 keys[i] = newMockHashKey(int64(i)) 206 vals[i] = int64(i) 207 lru.Put(keys[i], vals[i]) 208 } 209 c.Assert(int(lru.size), Equals, 3) 210 211 lru.Delete(keys[1]) 212 value, exists := lru.Get(keys[1]) 213 c.Assert(exists, IsFalse) 214 c.Assert(value, IsNil) 215 c.Assert(int(lru.size), Equals, 2) 216 217 _, exists = lru.Get(keys[0]) 218 c.Assert(exists, IsTrue) 219 220 _, exists = lru.Get(keys[2]) 221 c.Assert(exists, IsTrue) 222 } 223 224 func (s *testLRUCacheSuite) TestDeleteAll(c *C) { 225 maxMem, err := memory.MemTotal() 226 c.Assert(err, IsNil) 227 228 lru := NewSimpleLRUCache(3, 0, maxMem) 229 230 keys := make([]*mockCacheKey, 3) 231 vals := make([]int64, 3) 232 233 for i := 0; i < 3; i++ { 234 keys[i] = newMockHashKey(int64(i)) 235 vals[i] = int64(i) 236 lru.Put(keys[i], vals[i]) 237 } 238 c.Assert(int(lru.size), Equals, 3) 239 240 lru.DeleteAll() 241 242 for i := 0; i < 3; i++ { 243 value, exists := lru.Get(keys[i]) 244 c.Assert(exists, IsFalse) 245 c.Assert(value, IsNil) 246 c.Assert(int(lru.size), Equals, 0) 247 } 248 } 249 250 func (s *testLRUCacheSuite) TestValues(c *C) { 251 maxMem, err := memory.MemTotal() 252 c.Assert(err, IsNil) 253 254 lru := NewSimpleLRUCache(5, 0, maxMem) 255 256 keys := make([]*mockCacheKey, 5) 257 vals := make([]int64, 5) 258 259 for i := 0; i < 5; i++ { 260 keys[i] = newMockHashKey(int64(i)) 261 vals[i] = int64(i) 262 lru.Put(keys[i], vals[i]) 263 } 264 265 values := lru.Values() 266 c.Assert(len(values), Equals, 5) 267 for i := 0; i < 5; i++ { 268 c.Assert(values[i], Equals, int64(4-i)) 269 } 270 } 271 272 func (s *testLRUCacheSuite) TestPutProfileName(c *C) { 273 lru := NewSimpleLRUCache(3, 0, 10) 274 c.Assert(lru.capacity, Equals, uint(3)) 275 t := reflect.TypeOf(*lru) 276 pt := reflect.TypeOf(lru) 277 functionName := "" 278 for i := 0; i < pt.NumMethod(); i++ { 279 if pt.Method(i).Name == "Put" { 280 functionName = "Put" 281 } 282 } 283 pName := fmt.Sprintf("%s.(*%s).%s", t.PkgPath(), t.Name(), functionName) 284 c.Assert(pName, Equals, ProfileName) 285 }