diff --git a/pkg/cache/xfreecache/cache_test.go b/pkg/cache/xfreecache/cache_test.go index 67c51a46c1..ea257dff36 100644 --- a/pkg/cache/xfreecache/cache_test.go +++ b/pkg/cache/xfreecache/cache_test.go @@ -1,9 +1,8 @@ package xfreecache import ( - "fmt" - "encoding/json" + "fmt" "testing" "github.com/stretchr/testify/assert" diff --git a/pkg/cache/xfreecache/v2/cache.go b/pkg/cache/xfreecache/v2/cache.go index b2dbc32a97..e4dfc7dac1 100644 --- a/pkg/cache/xfreecache/v2/cache.go +++ b/pkg/cache/xfreecache/v2/cache.go @@ -1,13 +1,10 @@ package xfreecache import ( - "encoding/json" "fmt" "github.com/douyu/jupiter/pkg/xlog" "github.com/samber/lo" "go.uber.org/zap" - "google.golang.org/protobuf/proto" - "reflect" ) type storage interface { @@ -39,22 +36,13 @@ func (c *cache[K, V]) GetAndSetCacheMap(key string, ids []K, fn func([]K) (map[K // id去重 ids = lo.Uniq(ids) - idsNone := make([]K, 0) + idsNone := make([]K, 0, len(ids)) for _, id := range ids { cacheKey := c.getKey(key, id) if resT, innerErr := c.GetCacheData(cacheKey); innerErr == nil && resT != nil { var value V - if msg, ok := any(value).(proto.Message); ok { // Constrained to proto.Message - // Peek the type inside T (as T= *SomeProtoMsgType) - msgType := reflect.TypeOf(msg).Elem() - // Make a new one, and throw it back into T - msg = reflect.New(msgType).Interface().(proto.Message) - - err = proto.Unmarshal(resT, msg) - value = msg.(V) - } else { - err = json.Unmarshal(resT, &value) - } + // 反序列化 + value, err = unmarshal[V](resT) if err != nil { return } @@ -90,11 +78,8 @@ func (c *cache[K, V]) GetAndSetCacheMap(key string, ids []K, fn func([]K) (map[K if val, ok := v[id]; ok { cacheData = val } - if msg, ok := any(cacheData).(proto.Message); ok { - data, err = proto.Marshal(msg) - } else { - data, err = json.Marshal(cacheData) - } + // 序列化 + data, err = marshal(cacheData) if err != nil { xlog.Jupiter().Error("GetAndSetCacheMap Marshal", append(args, zap.Error(err))...) diff --git a/pkg/cache/xfreecache/v2/cache_test.go b/pkg/cache/xfreecache/v2/cache_test.go index 83f9f62478..6b9edae698 100644 --- a/pkg/cache/xfreecache/v2/cache_test.go +++ b/pkg/cache/xfreecache/v2/cache_test.go @@ -3,12 +3,13 @@ package xfreecache import ( "bytes" "fmt" + "testing" + "time" + "github.com/BurntSushi/toml" "github.com/douyu/jupiter/pkg/conf" helloworldv1 "github.com/douyu/jupiter/proto/helloworld/v1" "github.com/stretchr/testify/assert" - "testing" - "time" ) type Student struct { diff --git a/pkg/cache/xfreecache/v2/config.go b/pkg/cache/xfreecache/v2/config.go index ec05aa063c..f000111e7f 100644 --- a/pkg/cache/xfreecache/v2/config.go +++ b/pkg/cache/xfreecache/v2/config.go @@ -2,11 +2,11 @@ package xfreecache import ( "fmt" - cfg "github.com/douyu/jupiter/pkg/conf" "sync" "time" "github.com/coocood/freecache" + cfg "github.com/douyu/jupiter/pkg/conf" "github.com/douyu/jupiter/pkg/xlog" "go.uber.org/zap" ) diff --git a/pkg/cache/xfreecache/v2/encode.go b/pkg/cache/xfreecache/v2/encode.go new file mode 100644 index 0000000000..8fdff7ad20 --- /dev/null +++ b/pkg/cache/xfreecache/v2/encode.go @@ -0,0 +1,35 @@ +package xfreecache + +import ( + "encoding/json" + "reflect" + + "google.golang.org/protobuf/proto" +) + +// 反序列化,如果是pb格式,则使用proto序列化 +func unmarshal[T any](body []byte) (value T, err error) { + if msg, ok := any(value).(proto.Message); ok { // Constrained to proto.Message + // Peek the type inside T (as T= *SomeProtoMsgType) + msgType := reflect.TypeOf(msg).Elem() + + // Make a new one, and throw it back into T + msg = reflect.New(msgType).Interface().(proto.Message) + + err = proto.Unmarshal(body, msg) + value = msg.(T) + } else { + err = json.Unmarshal(body, &value) + } + return +} + +// 序列化,如果是pb格式,则使用proto序列化 +func marshal[T any](cacheData T) (data []byte, err error) { + if msg, ok := any(cacheData).(proto.Message); ok { + data, err = proto.Marshal(msg) + } else { + data, err = json.Marshal(cacheData) + } + return +} diff --git a/pkg/cache/xfreecache/v2/json_bench_test.go b/pkg/cache/xfreecache/v2/encode_bench_test.go similarity index 75% rename from pkg/cache/xfreecache/v2/json_bench_test.go rename to pkg/cache/xfreecache/v2/encode_bench_test.go index 9411f78830..1d4a40dafa 100644 --- a/pkg/cache/xfreecache/v2/json_bench_test.go +++ b/pkg/cache/xfreecache/v2/encode_bench_test.go @@ -2,10 +2,9 @@ package xfreecache import ( "encoding/json" - helloworldv1 "github.com/douyu/jupiter/proto/helloworld/v1" - "reflect" "testing" + helloworldv1 "github.com/douyu/jupiter/proto/helloworld/v1" jsoniter "github.com/json-iterator/go" "google.golang.org/protobuf/proto" ) @@ -66,7 +65,7 @@ func BenchmarkDecodeProto(b *testing.B) { func BenchmarkEncodeProto(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { - _, _ = proto.Marshal(helloReply) + _, _ = marshal[*helloworldv1.SayHiResponse](helloReply) } } @@ -74,23 +73,6 @@ func BenchmarkDecodeProtoWithReflect(b *testing.B) { res, _ := proto.Marshal(helloReply) b.ReportAllocs() for i := 0; i < b.N; i++ { - _ = protoUnmarshal[*helloworldv1.SayHiResponse](res) + _, _ = unmarshal[*helloworldv1.SayHiResponse](res) } } - -func protoUnmarshal[T any](body []byte) T { - var value T - - if msg, ok := any(value).(proto.Message); ok { // Constrained to proto.Message - // Peek the type inside T (as T= *SomeProtoMsgType) - msgType := reflect.TypeOf(msg).Elem() - - // Make a new one, and throw it back into T - msg = reflect.New(msgType).Interface().(proto.Message) - - _ = proto.Unmarshal(body, msg) - value = msg.(T) - } - - return value -}