上传底层反射优化代码
This commit is contained in:
parent
afecd0e065
commit
89ee5478d2
@ -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
|
||||
}
|
||||
|
@ -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...)
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 命令用于为哈希表中的字段值加上指定增量值。
|
||||
增量也可以为负数,相当于对指定字段进行减法操作。
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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 命令用于为哈希表中的字段值加上指定增量值。
|
||||
增量也可以为负数,相当于对指定字段进行减法操作。
|
||||
|
@ -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...)
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user