github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/internal/cache/lfucache/lfucache_test.go (about) 1 // Copyright 2021 The Bitalosdb author(hustxrb@163.com) and other contributors. 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 lfucache 16 17 import ( 18 "bytes" 19 "fmt" 20 "runtime" 21 "testing" 22 "time" 23 24 "github.com/zuoyebang/bitalosdb/internal/base" 25 "github.com/zuoyebang/bitalosdb/internal/cache/lrucache" 26 "github.com/zuoyebang/bitalosdb/internal/hash" 27 "github.com/zuoyebang/bitalosdb/internal/options" 28 ) 29 30 func testNewCache() *LfuCache { 31 opts := &options.CacheOptions{ 32 Size: 1 << 20, 33 Shards: 64, 34 } 35 mc := NewLfuCache(opts) 36 return mc 37 } 38 39 func TestFreq(t *testing.T) { 40 opts := &options.CacheOptions{ 41 Size: 1 << 20, 42 Shards: 2, 43 } 44 mc := NewLfuCache(opts) 45 46 value := []byte("mcache_valuemcache_valuemcache_valuemcache_valuemcache_valuemcache_valuemcache_valuemcache_valuemcache_valuemcache_valuemcache_valuemcache_valuemcache_valuemcache_valuemcache_valuemcache_valuemcache_valuemcache_valuemcache_valuemcache_value") 47 48 key := []byte("mcache") 49 khash := mc.GetKeyHash(key) 50 for i := 0; i < 500; i++ { 51 mc.Set(key, value, khash) 52 mc.Get(key, khash) 53 } 54 55 time.Sleep(5 * time.Second) 56 57 fmt.Printf("----------------------------------------compact----------------------------------------\n") 58 59 for i := 0; i < 500; i++ { 60 k := []byte(fmt.Sprintf("xxx_%d", i)) 61 mc.Set(k, value, mc.GetKeyHash(k)) 62 } 63 64 time.Sleep(10 * time.Second) 65 66 mc.Get(key, khash) 67 } 68 69 func TestLfucache_Shards(t *testing.T) { 70 for i := -1; i < 12; i++ { 71 opts := &options.CacheOptions{ 72 Size: 10 << 20, 73 Shards: 2, 74 Logger: base.DefaultLogger, 75 } 76 mc := NewLfuCache(opts) 77 fmt.Println(i, mc.shardNum) 78 mc.Close() 79 } 80 } 81 82 func Test_GetIter_VS_GET(t *testing.T) { 83 opts := &options.CacheOptions{ 84 Size: 512 << 20, 85 Shards: 2, 86 Logger: base.DefaultLogger, 87 } 88 lc := NewLfuCache(opts) 89 90 startNum := 0 91 totalNum := 1 << 20 92 totalNum_total := totalNum 93 94 khashs := make([]uint32, totalNum_total+1, totalNum_total+1) 95 value := []byte("v") 96 97 bt := time.Now() 98 for i := startNum; i <= totalNum_total; i++ { 99 key := []byte(fmt.Sprintf("lfucache_key_%d", i)) 100 khash := hash.Crc32(key) 101 khashs[i] = khash 102 if i <= totalNum { 103 lc.bucketByHash(khash).set(key, value) 104 } 105 } 106 et := time.Since(bt) 107 fmt.Printf("build lfucache time cost = %v\n", et) 108 109 printMemStats() 110 111 bt = time.Now() 112 for i := startNum; i <= totalNum_total; i++ { 113 key := []byte(fmt.Sprintf("lfucache_key_%d", i)) 114 khash := khashs[i] 115 val, closer, found := lc.bucketByHash(khash).getIter(key) 116 if found && bytes.Equal(val, value) { 117 closer() 118 } else if i <= totalNum { 119 fmt.Printf("lfucache get by iter fail, key=%s, val=%s\n", key, val) 120 } 121 } 122 et = time.Since(bt) 123 fmt.Printf("get by iter lfucache time cost = %v\n", et) 124 125 bt = time.Now() 126 for i := startNum; i <= totalNum_total; i++ { 127 key := []byte(fmt.Sprintf("lfucache_key_%d", i)) 128 khash := khashs[i] 129 val, closer, found := lc.bucketByHash(khash).get(key) 130 if found && bytes.Equal(val, value) { 131 closer() 132 } else if i <= totalNum { 133 fmt.Printf("lfucache get fail, key=%s, val=%s\n", key, val) 134 } 135 } 136 et = time.Since(bt) 137 fmt.Printf("get lfucache time cost = %v\n", et) 138 139 bt = time.Now() 140 for i := startNum; i <= totalNum_total; i++ { 141 key := []byte(fmt.Sprintf("lfucache_key_%d", i)) 142 khash := khashs[i] 143 found := lc.bucketByHash(khash).exist(key) 144 if !found && i <= totalNum { 145 fmt.Printf("lfucache exist fail, key=%s\n", key) 146 } 147 } 148 et = time.Since(bt) 149 fmt.Printf("exist lfucache time cost = %v\n", et) 150 } 151 152 func Test_LFU_VS_LRU(t *testing.T) { 153 startNum := 0 154 totalNum := 1 << 20 155 totalNum_total := totalNum 156 157 opts := &options.CacheOptions{ 158 Size: 512 << 20, 159 Shards: 64, 160 HashSize: totalNum, 161 Logger: base.DefaultLogger, 162 } 163 lfu := NewLfuCache(opts) 164 lru := lrucache.New(opts) 165 166 value := []byte("v") 167 168 bt := time.Now() 169 for i := startNum; i <= totalNum_total; i++ { 170 key := []byte(fmt.Sprintf("lfucache_key_%d", i)) 171 khash := hash.Crc32(key) 172 if i <= totalNum { 173 lfu.bucketByHash(khash).set(key, value) 174 } 175 } 176 et := time.Since(bt) 177 fmt.Printf("build lfucache time cost = %v\n", et) 178 179 printMemStats() 180 181 bt = time.Now() 182 for i := startNum; i <= totalNum_total; i++ { 183 key := []byte(fmt.Sprintf("lfucache_key_%d", i)) 184 if i <= totalNum { 185 lru.Set(key, value, lru.GetKeyHash(key)) 186 } 187 } 188 et = time.Since(bt) 189 fmt.Printf("build lrucache time cost = %v\n", et) 190 191 printMemStats() 192 193 bt = time.Now() 194 for i := startNum; i <= totalNum_total; i++ { 195 key := []byte(fmt.Sprintf("lfucache_key_%d", i)) 196 khash := hash.Crc32(key) 197 val, closer, found := lfu.bucketByHash(khash).get(key) 198 if found && bytes.Equal(val, value) { 199 closer() 200 } else if i <= totalNum { 201 fmt.Printf("lfucache get fail, key=%s, val=%s\n", key, val) 202 } 203 } 204 et = time.Since(bt) 205 fmt.Printf("get lfucache time cost = %v\n", et) 206 207 bt = time.Now() 208 for i := startNum; i <= totalNum_total; i++ { 209 key := []byte(fmt.Sprintf("lfucache_key_%d", i)) 210 val, vcloser, vexist := lru.Get(key, lru.GetKeyHash(key)) 211 if vexist && bytes.Equal(val, value) { 212 vcloser() 213 } else if i <= totalNum { 214 fmt.Printf("lrucache get fail, key=%s\n", key) 215 } 216 } 217 et = time.Since(bt) 218 fmt.Printf("get lrucache time cost = %v\n", et) 219 } 220 221 const MB = 1024 * 1024 222 223 func printMemStats() { 224 var m runtime.MemStats 225 runtime.ReadMemStats(&m) 226 fmt.Printf("Map MEM: Alloc=%vMB; TotalAlloc=%vMB; SYS=%vMB; Mallocs=%v; Frees=%v; HeapAlloc=%vMB; HeapSys=%vMB; HeapIdle=%vMB; HeapReleased=%vMB; GCSys=%vMB; NextGC=%vMB; NumGC=%v; NumForcedGC=%v\n", 227 m.Alloc/MB, m.TotalAlloc/MB, m.Sys/MB, m.Mallocs, m.Frees, m.HeapAlloc/MB, m.HeapSys/MB, m.HeapIdle/MB, m.HeapReleased/MB, 228 m.GCSys/MB, m.NextGC/MB, m.NumGC, m.NumForcedGC) 229 }