github.com/masterhung0112/hk_server/v5@v5.0.0-20220302090640-ec71aef15e1c/services/cache/lru_striped_bench_test.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package cache_test 5 6 import ( 7 "fmt" 8 "runtime" 9 "sync" 10 "testing" 11 12 "github.com/cespare/xxhash/v2" 13 "github.com/masterhung0112/hk_server/v5/services/cache" 14 ) 15 16 const ( 17 m = 500_000 18 ) 19 20 func BenchmarkLRUStriped(b *testing.B) { 21 opts := cache.LRUOptions{ 22 Name: "", 23 Size: 128, 24 DefaultExpiry: 0, 25 InvalidateClusterEvent: "", 26 StripedBuckets: runtime.NumCPU() - 1, 27 } 28 29 cache, err := cache.NewLRUStriped(opts) 30 if err != nil { 31 panic(err) 32 } 33 // prepare keys and initial cache values and set routine 34 keys := make([]string, 0, m) 35 // bucketKeys is to demonstrate that splitted locks is working correctly 36 // by assigning one sequence of key for each bucket. 37 bucketKeys := make([][]string, opts.StripedBuckets) 38 for i := 0; i < m; i++ { 39 key := fmt.Sprintf("%d-key-%d", i, i) 40 keys = append(keys, key) 41 bucketKey := xxhash.Sum64String(key) % uint64(opts.StripedBuckets) 42 bucketKeys[bucketKey] = append(bucketKeys[bucketKey], key) 43 } 44 for i := 0; i < opts.Size; i++ { 45 cache.Set(keys[i], "preflight") 46 } 47 48 wgGet := &sync.WaitGroup{} 49 wgSet := &sync.WaitGroup{} 50 // need buffered chan because if the set routine finished before we write into the chan, 51 // we're left without any consumer, making any write to the chan waiting forever. 52 stopSet := make(chan bool, 1) 53 set := func() { 54 defer wgSet.Done() 55 for i := 0; i < m; i++ { 56 select { 57 case <-stopSet: 58 return 59 default: 60 _ = cache.Set(keys[i], "ignored") 61 } 62 } 63 } 64 65 get := func(bucket int) { 66 defer wgGet.Done() 67 var out string 68 for i := 0; i < m; i++ { 69 _ = cache.Get(bucketKeys[bucket][i%opts.Size], &out) 70 } 71 } 72 73 b.StopTimer() 74 b.ResetTimer() 75 for i := 0; i < b.N; i++ { 76 wgSet.Add(1) 77 go set() 78 for j := 0; j < opts.StripedBuckets; j++ { 79 wgGet.Add(1) 80 go get(j) 81 } 82 83 b.StartTimer() 84 wgGet.Wait() 85 b.StopTimer() 86 87 stopSet <- true 88 wgSet.Wait() 89 } 90 }