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