上传底层反射优化代码

This commit is contained in:
liwei1dao 2022-07-12 17:13:59 +08:00
parent afecd0e065
commit 89ee5478d2
10 changed files with 198 additions and 6 deletions

View File

@ -100,7 +100,7 @@ func (this *Codec) DecoderOf(typ reflect2.Type) core.IDecoder {
Encoders: map[reflect2.Type]core.IEncoder{},
}
ptrType := typ.(*reflect2.UnsafePtrType)
decoder = factory.DecoderOfType(ctx, ptrType.Elem())
decoder = factory.DecoderOfType(ctx, ptrType)
this.addDecoderToCache(cacheKey, decoder)
return decoder
}

View File

@ -2,10 +2,14 @@ package codec
import (
"go_dreamfactory/lego/sys/codec/core"
"github.com/modern-go/reflect2"
)
type (
ISys interface {
DecoderOf(typ reflect2.Type) core.IDecoder
EncoderOf(typ reflect2.Type) core.IEncoder
MarshalJson(v interface{}, option ...core.ExecuteOption) ([]byte, error)
UnmarshalJson(data []byte, v interface{}, option ...core.ExecuteOption) error
MarshalMapJson(val interface{}, option ...core.ExecuteOption) (ret map[string]string, err error)
@ -26,7 +30,12 @@ func NewSys(option ...core.Option) (sys ISys, err error) {
sys, err = newSys(newOptionsByOption(option...))
return
}
func DecoderOf(typ reflect2.Type) core.IDecoder {
return defsys.DecoderOf(typ)
}
func EncoderOf(typ reflect2.Type) core.IEncoder {
return defsys.EncoderOf(typ)
}
func MarshalJson(v interface{}, option ...core.ExecuteOption) ([]byte, error) {
return defsys.MarshalJson(v, option...)
}

View File

@ -48,6 +48,15 @@ func (this *OptionalDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
}
}
func (this *OptionalDecoder) DecodeForMapJson(ptr unsafe.Pointer, extra map[string]string) (err error) {
if decoderMapJson, ok := this.ValueDecoder.(core.IDecoderMapJson); !ok {
err = fmt.Errorf("encoder %T not support EncodeToMapJson", this.ValueDecoder)
return
} else {
return decoderMapJson.DecodeForMapJson(ptr, extra)
}
}
type OptionalEncoder struct {
ValueEncoder core.IEncoder
}

View File

@ -57,7 +57,7 @@ func Test_sys_mapjson(t *testing.T) {
}
func Test_sys_reflect2(t *testing.T) {
data := []string{"123"}
data := []*Test1Data{}
ptr := reflect2.TypeOf(&data)
kind := ptr.Kind()
switch kind {
@ -76,6 +76,11 @@ func Test_sys_reflect2(t *testing.T) {
elemType := ptrType.Elem()
kind = elemType.Kind()
if kind == reflect.Slice {
sliceelem := elemType.(*reflect2.UnsafeSliceType).Elem()
sliceelemkind := sliceelem.Kind()
if sliceelemkind == reflect.Ptr {
return
}
return
}
return

View File

@ -46,6 +46,17 @@ func (this *Redis) HMSet(key string, v interface{}) (err error) {
return
}
func (this *Redis) HMSetForMap(key string, v map[string]string) (err error) {
agrs := make([]interface{}, 0)
agrs = append(agrs, "HMSET")
agrs = append(agrs, key)
for k, v := range v {
agrs = append(agrs, k, v)
}
err = this.client.Do(this.getContext(), agrs...).Err()
return
}
/*
Redis Hget 命令用于返回哈希表中指定字段的值
*/
@ -81,6 +92,21 @@ func (this *Redis) HGetAll(key string, v interface{}) (err error) {
return
}
/*
读取全部hash集合数据到map中
*/
func (this *Redis) HGetAllToMapString(key string) (result map[string]string, err error) {
cmd := redis.NewStringStringMapCmd(this.getContext(), "HGETALL", key)
this.client.Process(this.getContext(), cmd)
if result, err = cmd.Result(); err == nil {
if len(result) == 0 {
err = redis.Nil
return
}
}
return
}
/*
Redis Hincrby 命令用于为哈希表中的字段值加上指定增量值
增量也可以为负数相当于对指定字段进行减法操作

View File

@ -65,12 +65,14 @@ type (
HExists(key string, field string) (result bool, err error)
HGet(key string, field string, value interface{}) (err error)
HGetAll(key string, v interface{}) (err error)
HGetAllToMapString(key string) (result map[string]string, err error)
HIncrBy(key string, field string, value int) (err error)
HIncrByFloat(key string, field string, value float32) (err error)
Hkeys(key string) (result []string, err error)
Hlen(key string) (result int, err error)
HMGet(key string, v interface{}, fields ...string) (err error)
HMSet(key string, v interface{}) (err error)
HMSetForMap(key string, v map[string]string) (err error)
HSet(key string, field string, value interface{}) (err error)
HSetNX(key string, field string, value interface{}) (err error)
/*Set*/
@ -325,6 +327,9 @@ func HMGet(key string, v interface{}, fields ...string) (err error) {
func HMSet(key string, v interface{}) (err error) {
return defsys.HMSet(key, v)
}
func HMSetForMap(key string, v map[string]string) (err error) {
return defsys.HMSetForMap(key, v)
}
func HSet(key string, field string, value interface{}) (err error) {
return defsys.HSet(key, field, value)
}

View File

@ -213,6 +213,9 @@ func (this *Redis) HGet(key string, field string, value interface{}) (err error)
func (this *Redis) HGetAll(key string, v interface{}) (err error) {
return this.client.HGetAll(key, v)
}
func (this *Redis) HGetAllToMapString(key string) (result map[string]string, err error) {
return this.client.HGetAllToMapString(key)
}
func (this *Redis) HIncrBy(key string, field string, value int) (err error) {
return this.client.HIncrBy(key, field, value)
}
@ -231,6 +234,11 @@ func (this *Redis) HMGet(key string, v interface{}, fields ...string) (err error
func (this *Redis) HMSet(key string, v interface{}) (err error) {
return this.client.HMSet(key, v)
}
func (this *Redis) HMSetForMap(key string, v map[string]string) (err error) {
return this.client.HMSetForMap(key, v)
}
func (this *Redis) HSet(key string, field string, value interface{}) (err error) {
return this.client.HSet(key, field, value)
}

View File

@ -45,6 +45,16 @@ func (this *Redis) HMSet(key string, v interface{}) (err error) {
err = this.client.Do(this.getContext(), agrs...).Err()
return
}
func (this *Redis) HMSetForMap(key string, v map[string]string) (err error) {
agrs := make([]interface{}, 0)
agrs = append(agrs, "HMSET")
agrs = append(agrs, key)
for k, v := range v {
agrs = append(agrs, k, v)
}
err = this.client.Do(this.getContext(), agrs...).Err()
return
}
/*
Redis Hget 命令用于返回哈希表中指定字段的值
@ -76,6 +86,21 @@ func (this *Redis) HGetAll(key string, v interface{}) (err error) {
return
}
/*
读取全部hash集合数据到map中
*/
func (this *Redis) HGetAllToMapString(key string) (result map[string]string, err error) {
cmd := redis.NewStringStringMapCmd(this.getContext(), "HGETALL", key)
this.client.Process(this.getContext(), cmd)
if result, err = cmd.Result(); err == nil {
if len(result) == 0 {
err = redis.Nil
return
}
}
return
}
/*
Redis Hincrby 命令用于为哈希表中的字段值加上指定增量值
增量也可以为负数相当于对指定字段进行减法操作

View File

@ -6,6 +6,8 @@ import (
"go_dreamfactory/comm"
"go_dreamfactory/lego/core"
"go_dreamfactory/lego/core/cbase"
"go_dreamfactory/lego/sys/codec"
ccore "go_dreamfactory/lego/sys/codec/core"
"go_dreamfactory/lego/sys/log"
"go_dreamfactory/lego/sys/mgo"
"go_dreamfactory/lego/sys/redis"
@ -13,7 +15,9 @@ import (
"go_dreamfactory/sys/db"
"reflect"
"time"
"unsafe"
"github.com/modern-go/reflect2"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
@ -221,8 +225,8 @@ func (this *MCompModel) Get(uid string, data interface{}) (err error) {
return
}
//获取列表数据 注意 data 必须啊转 切片的指针 *[]type
func (this *MCompModel) GetList(uid string, data interface{}) (err error) {
//获取列表数据 注意 data 必须是 切片的指针 *[]type 暂时废弃
func (this *MCompModel) mGetList(uid string, data interface{}) (err error) {
var keys map[string]string = make(map[string]string)
var c *mongo.Cursor
t := reflect.TypeOf(data)
@ -312,6 +316,107 @@ func (this *MCompModel) GetList(uid string, data interface{}) (err error) {
return err
}
//获取列表数据 注意 data 必须是 切片的指针 *[]type
func (this *MCompModel) GetList(uid string, data interface{}) (err error) {
var (
dtype reflect2.Type
dkind reflect.Kind
sType reflect2.Type
sliceType *reflect2.UnsafeSliceType
sliceelemType reflect2.Type
decoder ccore.IDecoderMapJson
encoder ccore.IEncoderMapJson
dptr unsafe.Pointer
elemPtr unsafe.Pointer
n int
ok bool
keys map[string]string
cdata map[string]string
c *mongo.Cursor
)
keys = make(map[string]string)
dptr = reflect2.PtrOf(data)
dtype = reflect2.TypeOf(data)
dkind = dtype.Kind()
if dkind != reflect.Ptr {
err = fmt.Errorf("MCompModel: GetList(non-pointer %T)", data)
return
}
sType = dtype.(*reflect2.UnsafePtrType).Elem()
if sType.Kind() != reflect.Slice {
err = fmt.Errorf("MCompModel: GetList(data no slice %T)", data)
return
}
sliceType = sType.(*reflect2.UnsafeSliceType)
sliceelemType = sliceType.Elem()
if sliceelemType.Kind() != reflect.Ptr {
err = fmt.Errorf("MCompModel: GetList(sliceelemType non-pointer %T)", data)
return
}
if decoder, ok = codec.DecoderOf(sliceelemType).(ccore.IDecoderMapJson); !ok {
err = fmt.Errorf("MCompModel: GetList(data not support MarshalMapJson %T)", data)
return
}
keys, err = this.Redis.HGetAllToMapString(this.ukey(uid))
if err == nil {
n = 0
for _, v := range keys {
if cdata, err = this.Redis.HGetAllToMapString(v); err != nil {
return
}
sliceType.UnsafeGrow(dptr, n+1)
elemPtr = sliceType.UnsafeGetIndex(dptr, n)
if *((*unsafe.Pointer)(elemPtr)) == nil {
newPtr := sliceelemType.UnsafeNew()
decoder.DecodeForMapJson(newPtr, cdata)
*((*unsafe.Pointer)(elemPtr)) = newPtr
} else {
decoder.DecodeForMapJson(*((*unsafe.Pointer)(elemPtr)), cdata)
}
n++
}
}
if err == redis.RedisNil {
//query from mgo
if c, err = this.DB.Find(core.SqlTable(this.TableName), bson.M{"uid": uid}); err != nil {
return err
} else {
if encoder, ok = codec.EncoderOf(sliceelemType).(ccore.IEncoderMapJson); !ok {
err = fmt.Errorf("MCompModel: GetList(data not support UnMarshalMapJson %T)", data)
return
}
n = 0
for c.Next(context.Background()) {
_id := c.Current.Lookup("_id").StringValue()
sliceType.UnsafeGrow(dptr, n+1)
elemPtr = sliceType.UnsafeGetIndex(dptr, n)
if *((*unsafe.Pointer)(elemPtr)) == nil {
newPtr := sliceelemType.UnsafeNew()
*((*unsafe.Pointer)(elemPtr)) = newPtr
}
elem := sliceType.GetIndex(data, n)
n++
if err = c.Decode(elem); err != nil {
return
}
if cdata, err = encoder.EncodeToMapJson(*((*unsafe.Pointer)(elemPtr))); err != nil {
return
}
key := this.ukeylist(uid, _id)
if err = this.Redis.HMSetForMap(key, cdata); err != nil {
return
}
keys[_id] = key
}
if err = this.Redis.HMSetForMap(this.ukey(uid), keys); err != nil {
return
}
}
}
return err
}
//读取单个数据中 多个字段数据
func (this *MCompModel) GetFields(uid string, data interface{}, fields ...string) (err error) {
this.Redis.HMGet(this.ukey(uid), data, fields...)

View File

@ -84,7 +84,7 @@ func TestMain(m *testing.M) {
func Test_Modules(t *testing.T) {
data, _ := ptypes.MarshalAny(&pb.ItemsGetlistReq{})
s_gateComp.ReceiveMsg(context.Background(), &pb.AgentMessage{UserId: "0_62c259916d8cf3e4e06311a8", MainType: "items", SubType: "getlist", Message: data}, &pb.RPCMessageReply{})
s_gateComp.ReceiveMsg(context.Background(), &pb.AgentMessage{UserId: "0_62bd7bc609320345a244f372", MainType: "items", SubType: "getlist", Message: data}, &pb.RPCMessageReply{})
// items, err := module.db_comp.Pack_QueryUserPack("liwei1dao")
log.Debugf("data:%v", data)
}