上传底层反射优化代码

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{}, Encoders: map[reflect2.Type]core.IEncoder{},
} }
ptrType := typ.(*reflect2.UnsafePtrType) ptrType := typ.(*reflect2.UnsafePtrType)
decoder = factory.DecoderOfType(ctx, ptrType.Elem()) decoder = factory.DecoderOfType(ctx, ptrType)
this.addDecoderToCache(cacheKey, decoder) this.addDecoderToCache(cacheKey, decoder)
return decoder return decoder
} }

View File

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

View File

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

View File

@ -46,6 +46,17 @@ func (this *Redis) HMSet(key string, v interface{}) (err error) {
return 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 命令用于返回哈希表中指定字段的值 Redis Hget 命令用于返回哈希表中指定字段的值
*/ */
@ -81,6 +92,21 @@ func (this *Redis) HGetAll(key string, v interface{}) (err error) {
return 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 命令用于为哈希表中的字段值加上指定增量值 Redis Hincrby 命令用于为哈希表中的字段值加上指定增量值
增量也可以为负数相当于对指定字段进行减法操作 增量也可以为负数相当于对指定字段进行减法操作

View File

@ -65,12 +65,14 @@ type (
HExists(key string, field string) (result bool, err error) HExists(key string, field string) (result bool, err error)
HGet(key string, field string, value interface{}) (err error) HGet(key string, field string, value interface{}) (err error)
HGetAll(key string, v 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) HIncrBy(key string, field string, value int) (err error)
HIncrByFloat(key string, field string, value float32) (err error) HIncrByFloat(key string, field string, value float32) (err error)
Hkeys(key string) (result []string, err error) Hkeys(key string) (result []string, err error)
Hlen(key string) (result int, err error) Hlen(key string) (result int, err error)
HMGet(key string, v interface{}, fields ...string) (err error) HMGet(key string, v interface{}, fields ...string) (err error)
HMSet(key string, v interface{}) (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) HSet(key string, field string, value interface{}) (err error)
HSetNX(key string, field string, value interface{}) (err error) HSetNX(key string, field string, value interface{}) (err error)
/*Set*/ /*Set*/
@ -325,6 +327,9 @@ func HMGet(key string, v interface{}, fields ...string) (err error) {
func HMSet(key string, v interface{}) (err error) { func HMSet(key string, v interface{}) (err error) {
return defsys.HMSet(key, v) 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) { func HSet(key string, field string, value interface{}) (err error) {
return defsys.HSet(key, field, value) 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) { func (this *Redis) HGetAll(key string, v interface{}) (err error) {
return this.client.HGetAll(key, v) 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) { func (this *Redis) HIncrBy(key string, field string, value int) (err error) {
return this.client.HIncrBy(key, field, value) 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) { func (this *Redis) HMSet(key string, v interface{}) (err error) {
return this.client.HMSet(key, v) 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) { func (this *Redis) HSet(key string, field string, value interface{}) (err error) {
return this.client.HSet(key, field, value) 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() err = this.client.Do(this.getContext(), agrs...).Err()
return 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 命令用于返回哈希表中指定字段的值 Redis Hget 命令用于返回哈希表中指定字段的值
@ -76,6 +86,21 @@ func (this *Redis) HGetAll(key string, v interface{}) (err error) {
return 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 命令用于为哈希表中的字段值加上指定增量值 Redis Hincrby 命令用于为哈希表中的字段值加上指定增量值
增量也可以为负数相当于对指定字段进行减法操作 增量也可以为负数相当于对指定字段进行减法操作

View File

@ -6,6 +6,8 @@ import (
"go_dreamfactory/comm" "go_dreamfactory/comm"
"go_dreamfactory/lego/core" "go_dreamfactory/lego/core"
"go_dreamfactory/lego/core/cbase" "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/log"
"go_dreamfactory/lego/sys/mgo" "go_dreamfactory/lego/sys/mgo"
"go_dreamfactory/lego/sys/redis" "go_dreamfactory/lego/sys/redis"
@ -13,7 +15,9 @@ import (
"go_dreamfactory/sys/db" "go_dreamfactory/sys/db"
"reflect" "reflect"
"time" "time"
"unsafe"
"github.com/modern-go/reflect2"
"go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo"
@ -221,8 +225,8 @@ func (this *MCompModel) Get(uid string, data interface{}) (err error) {
return return
} }
//获取列表数据 注意 data 必须啊转 切片的指针 *[]type //获取列表数据 注意 data 必须是 切片的指针 *[]type 暂时废弃
func (this *MCompModel) GetList(uid string, data interface{}) (err error) { func (this *MCompModel) mGetList(uid string, data interface{}) (err error) {
var keys map[string]string = make(map[string]string) var keys map[string]string = make(map[string]string)
var c *mongo.Cursor var c *mongo.Cursor
t := reflect.TypeOf(data) t := reflect.TypeOf(data)
@ -312,6 +316,107 @@ func (this *MCompModel) GetList(uid string, data interface{}) (err error) {
return err 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) { func (this *MCompModel) GetFields(uid string, data interface{}, fields ...string) (err error) {
this.Redis.HMGet(this.ukey(uid), data, fields...) 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) { func Test_Modules(t *testing.T) {
data, _ := ptypes.MarshalAny(&pb.ItemsGetlistReq{}) 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") // items, err := module.db_comp.Pack_QueryUserPack("liwei1dao")
log.Debugf("data:%v", data) log.Debugf("data:%v", data)
} }