github.com/jxskiss/gopkg/v2@v2.14.9-0.20240514120614-899f3e7952b4/perf/lru/sharded_test.go (about) 1 package lru 2 3 import ( 4 "math/rand" 5 "runtime" 6 "testing" 7 "time" 8 ) 9 10 func createFilledShardedCache(ttl time.Duration) *ShardedCache[int64, int64] { 11 c := NewShardedCache[int64, int64](8, 500) 12 for i := 0; i < 1000; i++ { 13 key := int64(rand.Intn(5000)) 14 c.Set(key, key, ttl) 15 } 16 return c 17 } 18 19 func TestShardedBasicEviction(t *testing.T) { 20 t.Parallel() 21 c := NewShardedCache[string, string](4, 3) 22 if _, ok, _ := c.Get("a"); ok { 23 t.Error("") 24 } 25 26 c.Set("b", "vb", 2*time.Second) 27 c.Set("a", "va", time.Second) 28 c.Set("c", "vc", 3*time.Second) 29 30 if v, _, _ := c.Get("a"); v != "va" { 31 t.Error("va") 32 } 33 if v, _, _ := c.Get("b"); v != "vb" { 34 t.Error("vb") 35 } 36 if v, _, _ := c.Get("c"); v != "vc" { 37 t.Error("vc") 38 } 39 40 c.MSet(map[string]string{"h": "vh", "i": "vi"}, time.Second) 41 if v, _, _ := c.Get("h"); v != "vh" { 42 t.Error("vh") 43 } 44 if v, _, _ := c.Get("i"); v != "vi" { 45 t.Error("vi") 46 } 47 48 m := c.MGet("h", "i") 49 if m["h"] != "vh" { 50 t.Error("expecting MSet and NGet to work") 51 } 52 if m["i"] != "vi" { 53 t.Error("expecting MSet and MGet to work") 54 } 55 } 56 57 func TestShardedConcurrentGet(t *testing.T) { 58 t.Parallel() 59 c := createFilledShardedCache(time.Second) 60 s := createRandInts(50000) 61 62 runConcurrentGetTest(t, c, s) 63 } 64 65 func TestShardedConcurrentSet(t *testing.T) { 66 t.Parallel() 67 c := createFilledShardedCache(time.Second) 68 s := createRandInts(5000) 69 70 runConcurrentSetTest(t, c, s) 71 } 72 73 func TestShardedConcurrentGetSet(t *testing.T) { 74 t.Parallel() 75 c := createFilledShardedCache(time.Second) 76 s := createRandInts(5000) 77 78 runConcurrentGetSetTest(t, c, s) 79 } 80 81 func BenchmarkShardedConcurrentGetLRUCache(bb *testing.B) { 82 c := createFilledShardedCache(time.Second) 83 s := createRandInts(5000) 84 85 bb.ReportAllocs() 86 bb.ResetTimer() 87 cpu := runtime.GOMAXPROCS(0) 88 ch := make(chan bool) 89 worker := func() { 90 for i := 0; i < bb.N/cpu; i++ { 91 c.Get(s[i%5000]) 92 } 93 ch <- true 94 } 95 for i := 0; i < cpu; i++ { 96 go worker() 97 } 98 for i := 0; i < cpu; i++ { 99 _ = <-ch 100 } 101 } 102 103 func BenchmarkShardedConcurrentSetLRUCache(bb *testing.B) { 104 c := createFilledShardedCache(time.Second) 105 s := createRandInts(5000) 106 107 bb.ReportAllocs() 108 bb.ResetTimer() 109 cpu := runtime.GOMAXPROCS(0) 110 ch := make(chan bool) 111 worker := func() { 112 ttl := 4 * time.Second 113 for i := 0; i < bb.N/cpu; i++ { 114 key := s[i%5000] 115 c.Set(key, key, ttl) 116 } 117 ch <- true 118 } 119 for i := 0; i < cpu; i++ { 120 go worker() 121 } 122 for i := 0; i < cpu; i++ { 123 _ = <-ch 124 } 125 } 126 127 // No expiry 128 func BenchmarkShardedConcurrentSetNXLRUCache(bb *testing.B) { 129 c := createFilledShardedCache(time.Second) 130 s := createRandInts(5000) 131 132 bb.ReportAllocs() 133 bb.ResetTimer() 134 cpu := runtime.GOMAXPROCS(0) 135 ch := make(chan bool) 136 worker := func() { 137 for i := 0; i < bb.N/cpu; i++ { 138 key := s[i%5000] 139 c.Set(key, key, 0) 140 } 141 ch <- true 142 } 143 for i := 0; i < cpu; i++ { 144 go worker() 145 } 146 for i := 0; i < cpu; i++ { 147 _ = <-ch 148 } 149 }