diff --git a/pkg/cache/xfreecache/v2/cache.go b/pkg/cache/xfreecache/v2/cache.go index 8fc8749116..46d6ede41b 100644 --- a/pkg/cache/xfreecache/v2/cache.go +++ b/pkg/cache/xfreecache/v2/cache.go @@ -5,6 +5,7 @@ import ( "github.com/douyu/jupiter/pkg/xlog" "github.com/samber/lo" "go.uber.org/zap" + "reflect" ) type storage interface { @@ -67,6 +68,7 @@ func (c *cache[K, V]) SetCacheMap(key string, ids []K, fn func([]K) (map[K]V, er } func (c *cache[K, V]) getCacheMap(key string, ids []K) (v map[K]V, idsNone []K) { + var zero V v = make(map[K]V) idsNone = make([]K, 0, len(ids)) @@ -82,7 +84,9 @@ func (c *cache[K, V]) getCacheMap(key string, ids []K) (v map[K]V, idsNone []K) if innerErr != nil { xlog.Jupiter().Error("cache unmarshalWithPool", zap.String("key", key), zap.Error(innerErr)) } else { - v[id] = value + if !reflect.DeepEqual(value, zero) { + v[id] = value + } } } if innerErr != nil { diff --git a/pkg/cache/xfreecache/v2/cache_null_test.go b/pkg/cache/xfreecache/v2/cache_null_test.go new file mode 100644 index 0000000000..b09cc865f8 --- /dev/null +++ b/pkg/cache/xfreecache/v2/cache_null_test.go @@ -0,0 +1,202 @@ +package xfreecache + +import ( + "fmt" + helloworldv1 "github.com/douyu/jupiter/proto/helloworld/v1" + "github.com/stretchr/testify/assert" + "testing" +) + +// 测试相关值为空的测试用例 + +func Test_cache_proto_Null_GetAndSetCacheMap(t *testing.T) { + type args struct { + ids []int64 + } + // 初始化测试数据和测试用例 + data := map[int64]*helloworldv1.SayHiRequest{2: {Name: "2"}, 3: {Name: "3"}, 4: {Name: "4"}, 5: {Name: "5"}, 6: {Name: "6"}} + tests := []struct { + args args + wantV map[int64]*helloworldv1.SayHiRequest + }{ + { + args: args{ + ids: []int64{1, 2, 1, 3}, + }, + wantV: map[int64]*helloworldv1.SayHiRequest{2: data[2], 3: data[3]}, + }, + { + args: args{ + ids: []int64{1, 2, 3, 4}, + }, + wantV: map[int64]*helloworldv1.SayHiRequest{2: data[2], 3: data[3], 4: data[4]}, + }, + { + args: args{ + ids: []int64{1, 5, 6}, + }, + wantV: map[int64]*helloworldv1.SayHiRequest{5: data[5], 6: data[6]}, + }, + { + args: args{ + ids: []int64{1, 2, 3}, + }, + wantV: map[int64]*helloworldv1.SayHiRequest{2: data[2], 3: data[3]}, + }, + } + + missCount := 0 + for _, tt := range tests { + c := New[int64, *helloworldv1.SayHiRequest](DefaultConfig()) + gotV, err := c.GetAndSetCacheMap("Test_cache_proto_Null_GetAndSetCacheMap", tt.args.ids, func(in []int64) (map[int64]*helloworldv1.SayHiRequest, error) { + missCount++ + res := make(map[int64]*helloworldv1.SayHiRequest) + for _, uid := range in { + if val, ok := data[uid]; ok { + res[uid] = val + } + } + fmt.Println("======== in =========") + fmt.Println(res) + return res, nil + }) + fmt.Println("======== out =========") + fmt.Println(gotV) + assert.Nil(t, err, fmt.Sprintf("GetAndSetCacheMap(%v)", tt.args.ids)) + assert.Equalf(t, len(gotV), len(tt.wantV), "GetAndSetCacheMap(%v) len", tt.args.ids) + for k, v := range gotV { + val, ok := tt.wantV[k] + assert.Equalf(t, ok, true, "GetAndSetCacheMap(%v) ok", tt.args.ids) + assert.Equalf(t, v.GetName(), val.GetName(), "GetAndSetCacheMap(%v) val", tt.args.ids) + } + } + assert.Equalf(t, missCount, 3, "GetAndSetCacheMap miss count error") +} + +func Test_cache_json_Null_GetAndSetCacheMap(t *testing.T) { + type args struct { + ids []int64 + } + // 初始化测试数据和测试用例 + data := map[int64]*Student{2: {Name: "2"}, 3: {Name: "3"}, 4: {Name: "4"}, 5: {Name: "5"}, 6: {Name: "6"}} + tests := []struct { + args args + wantV map[int64]*Student + }{ + { + args: args{ + ids: []int64{1, 2, 1, 3}, + }, + wantV: map[int64]*Student{2: data[2], 3: data[3]}, + }, + { + args: args{ + ids: []int64{1, 2, 3, 4}, + }, + wantV: map[int64]*Student{2: data[2], 3: data[3], 4: data[4]}, + }, + { + args: args{ + ids: []int64{1, 5, 6}, + }, + wantV: map[int64]*Student{5: data[5], 6: data[6]}, + }, + { + args: args{ + ids: []int64{1, 2, 3}, + }, + wantV: map[int64]*Student{2: data[2], 3: data[3]}, + }, + } + + missCount := 0 + for _, tt := range tests { + c := New[int64, *Student](DefaultConfig()) + gotV, err := c.GetAndSetCacheMap("Test_cache_json_Null_GetAndSetCacheMap", tt.args.ids, func(in []int64) (map[int64]*Student, error) { + missCount++ + res := make(map[int64]*Student) + for _, uid := range in { + if val, ok := data[uid]; ok { + res[uid] = val + } + } + fmt.Println("======== in =========") + fmt.Println(res) + return res, nil + }) + fmt.Println("======== out =========") + fmt.Println(gotV) + assert.Nil(t, err, fmt.Sprintf("GetAndSetCacheMap(%v)", tt.args.ids)) + assert.Equalf(t, len(gotV), len(tt.wantV), "GetAndSetCacheMap(%v) len", tt.args.ids) + for k, v := range gotV { + val, ok := tt.wantV[k] + assert.Equalf(t, ok, true, "GetAndSetCacheMap(%v) ok", tt.args.ids) + assert.Equalf(t, v.Name, val.Name, "GetAndSetCacheMap(%v) val", tt.args.ids) + } + } + assert.Equalf(t, missCount, 3, "GetAndSetCacheMap miss count error") +} + +func Test_cache_struct_Null_GetAndSetCacheMap(t *testing.T) { + type args struct { + ids []int64 + } + // 初始化测试数据和测试用例 + data := map[int64]Student{2: {Name: "2"}, 3: {Name: "3"}, 4: {Name: "4"}, 5: {Name: "5"}, 6: {Name: "6"}} + tests := []struct { + args args + wantV map[int64]Student + }{ + { + args: args{ + ids: []int64{1, 2, 1, 3}, + }, + wantV: map[int64]Student{2: data[2], 3: data[3]}, + }, + { + args: args{ + ids: []int64{1, 2, 3, 4}, + }, + wantV: map[int64]Student{2: data[2], 3: data[3], 4: data[4]}, + }, + { + args: args{ + ids: []int64{1, 5, 6}, + }, + wantV: map[int64]Student{5: data[5], 6: data[6]}, + }, + { + args: args{ + ids: []int64{1, 2, 3}, + }, + wantV: map[int64]Student{2: data[2], 3: data[3]}, + }, + } + + missCount := 0 + for _, tt := range tests { + c := New[int64, Student](DefaultConfig()) + gotV, err := c.GetAndSetCacheMap("Test_cache_struct_Null_GetAndSetCacheMap", tt.args.ids, func(in []int64) (map[int64]Student, error) { + missCount++ + res := make(map[int64]Student) + for _, uid := range in { + if val, ok := data[uid]; ok { + res[uid] = val + } + } + fmt.Println("======== in =========") + fmt.Println(res) + return res, nil + }) + fmt.Println("======== out =========") + fmt.Println(gotV) + assert.Nil(t, err, fmt.Sprintf("GetAndSetCacheMap(%v)", tt.args.ids)) + assert.Equalf(t, len(gotV), len(tt.wantV), "GetAndSetCacheMap(%v) len", tt.args.ids) + for k, v := range gotV { + val, ok := tt.wantV[k] + assert.Equalf(t, ok, true, "GetAndSetCacheMap(%v) ok", tt.args.ids) + assert.Equalf(t, v.Name, val.Name, "GetAndSetCacheMap(%v) val", tt.args.ids) + } + } + assert.Equalf(t, missCount, 3, "GetAndSetCacheMap miss count error") +}