rft: using reference type to improve performance
diff --git a/decode.go b/decode.go
index 35de60e..25ae24a 100644
--- a/decode.go
+++ b/decode.go
@@ -35,7 +35,7 @@
// record type refs, both list and map need it
// todo: map
typeRefs *TypeRefs
- classInfoList []classInfo
+ classInfoList []*classInfo
isSkip bool
}
diff --git a/encode.go b/encode.go
index b0344d1..f20a476 100644
--- a/encode.go
+++ b/encode.go
@@ -33,7 +33,7 @@
// Encoder struct
type Encoder struct {
- classInfoList []classInfo
+ classInfoList []*classInfo
buffer []byte
refMap map[unsafe.Pointer]_refElem
}
diff --git a/java_collection.go b/java_collection.go
index 5e66514..d669d12 100644
--- a/java_collection.go
+++ b/java_collection.go
@@ -88,7 +88,7 @@
return nil
}
-func (JavaCollectionSerializer) DecObject(d *Decoder, typ reflect.Type, cls classInfo) (interface{}, error) {
+func (JavaCollectionSerializer) DecObject(d *Decoder, typ reflect.Type, cls *classInfo) (interface{}, error) {
//for the java impl of hessian encode collections as list, which will not be decoded as object in go impl, this method should not be called
return nil, perrors.New("unexpected collection decode call")
}
diff --git a/java_sql_time.go b/java_sql_time.go
index a359e8b..51e3abf 100644
--- a/java_sql_time.go
+++ b/java_sql_time.go
@@ -54,7 +54,7 @@
i int
idx int
err error
- clsDef classInfo
+ clsDef *classInfo
className string
ptrV reflect.Value
)
@@ -116,7 +116,7 @@
}
// nolint
-func (JavaSqlTimeSerializer) DecObject(d *Decoder, typ reflect.Type, cls classInfo) (interface{}, error) {
+func (JavaSqlTimeSerializer) DecObject(d *Decoder, typ reflect.Type, cls *classInfo) (interface{}, error) {
if typ.Kind() != reflect.Struct {
return nil, perrors.Errorf("wrong type expect Struct but get:%s", typ.String())
diff --git a/java_unknown_exception.go b/java_unknown_exception.go
index 1b4196c..0663c4f 100644
--- a/java_unknown_exception.go
+++ b/java_unknown_exception.go
@@ -28,13 +28,13 @@
var exceptionCheckMutex sync.Mutex
-func checkAndGetException(cls classInfo) (structInfo, bool) {
+func checkAndGetException(cls *classInfo) (*structInfo, bool) {
if len(cls.fieldNameList) < 4 {
- return structInfo{}, false
+ return nil, false
}
var (
- throwable structInfo
+ throwable *structInfo
ok bool
)
var count = 0
diff --git a/java_unknown_exception_test.go b/java_unknown_exception_test.go
index ea24321..20c8e6c 100644
--- a/java_unknown_exception_test.go
+++ b/java_unknown_exception_test.go
@@ -25,7 +25,7 @@
)
func TestCheckAndGetException(t *testing.T) {
- clazzInfo1 := classInfo{
+ clazzInfo1 := &classInfo{
javaName: "com.test.UserDefinedException",
fieldNameList: []string{"detailMessage", "code", "suppressedExceptions", "stackTrace", "cause"},
}
@@ -35,11 +35,11 @@
assert.Equal(t, s.javaName, "com.test.UserDefinedException")
assert.Equal(t, s.goName, "hessian.UnknownException")
- clazzInfo2 := classInfo{
+ clazzInfo2 := &classInfo{
javaName: "com.test.UserDefinedException",
fieldNameList: []string{"detailMessage", "code", "suppressedExceptions", "cause"},
}
s, b = checkAndGetException(clazzInfo2)
assert.False(t, b)
- assert.Equal(t, s, structInfo{})
+ assert.Nil(t, s)
}
diff --git a/list.go b/list.go
index d8ed019..8c70310 100644
--- a/list.go
+++ b/list.go
@@ -114,10 +114,11 @@
if sliceTy == nil {
tpStructInfo, _ := getStructInfo(javaname)
- tp := tpStructInfo.typ
- if tp == nil {
+ if tpStructInfo == nil || tpStructInfo.typ == nil {
return nil
}
+
+ tp := tpStructInfo.typ
if tp.Kind() != reflect.Ptr {
tp = reflect.New(tp).Type()
}
diff --git a/object.go b/object.go
index bec2de4..b398f25 100644
--- a/object.go
+++ b/object.go
@@ -104,7 +104,7 @@
idx int
num int
err error
- clsDef classInfo
+ clsDef *classInfo
)
vv := reflect.ValueOf(v)
@@ -292,7 +292,7 @@
fieldList[i] = fieldName
}
- return classInfo{javaName: clsName, fieldNameList: fieldList}, nil
+ return &classInfo{javaName: clsName, fieldNameList: fieldList}, nil
}
type fieldInfo struct {
@@ -362,7 +362,7 @@
return []int{}, nil, perrors.Errorf("failed to find field %s", name)
}
-func (d *Decoder) decInstance(typ reflect.Type, cls classInfo) (interface{}, error) {
+func (d *Decoder) decInstance(typ reflect.Type, cls *classInfo) (interface{}, error) {
if typ.Kind() != reflect.Struct {
return nil, perrors.Errorf("wrong type expect Struct but get:%s", typ.String())
}
@@ -537,15 +537,15 @@
return vRef.Interface(), nil
}
-func (d *Decoder) appendClsDef(cd classInfo) {
+func (d *Decoder) appendClsDef(cd *classInfo) {
d.classInfoList = append(d.classInfoList, cd)
}
-func (d *Decoder) getStructDefByIndex(idx int) (reflect.Type, classInfo, error) {
+func (d *Decoder) getStructDefByIndex(idx int) (reflect.Type, *classInfo, error) {
var (
ok bool
- cls classInfo
- s structInfo
+ cls *classInfo
+ s *structInfo
err error
)
@@ -573,7 +573,7 @@
err error
enumName string
ok bool
- info structInfo
+ info *structInfo
enumValue JavaEnum
)
enumName, err = d.decString(TAG_READ) // java enum class member is "name"
@@ -591,7 +591,7 @@
}
// skip this object
-func (d *Decoder) skip(cls classInfo) error {
+func (d *Decoder) skip(cls *classInfo) error {
len := len(cls.fieldNameList)
if len < 1 {
return nil
@@ -613,7 +613,7 @@
idx int32
err error
typ reflect.Type
- cls classInfo
+ cls *classInfo
)
if flag != TAG_READ {
@@ -632,7 +632,7 @@
if err != nil {
return nil, perrors.Wrap(err, "decObject->decClassDef byte double")
}
- cls, _ = clsDef.(classInfo)
+ cls, _ = clsDef.(*classInfo)
//add to slice
d.appendClsDef(cls)
diff --git a/object_test.go b/object_test.go
index 1bdeafa..7e59157 100644
--- a/object_test.go
+++ b/object_test.go
@@ -564,9 +564,9 @@
func TestSkip(t *testing.T) {
// clear pojo
- pojoRegistry = POJORegistry{
+ pojoRegistry = &POJORegistry{
j2g: make(map[string]string),
- registry: make(map[string]structInfo),
+ registry: make(map[string]*structInfo),
}
testDecodeFrameworkWithSkip(t, "replyObject_0", nil)
testDecodeFrameworkWithSkip(t, "replyObject_1", nil)
diff --git a/pojo.go b/pojo.go
index 8ed2e42..272037e 100644
--- a/pojo.go
+++ b/pojo.go
@@ -89,15 +89,15 @@
// POJORegistry pojo registry struct
type POJORegistry struct {
sync.RWMutex
- classInfoList []classInfo // {class name, field name list...} list
- j2g map[string]string // java class name --> go struct name
- registry map[string]structInfo // go class name --> go struct info
+ classInfoList []*classInfo // {class name, field name list...} list
+ j2g map[string]string // java class name --> go struct name
+ registry map[string]*structInfo // go class name --> go struct info
}
var (
- pojoRegistry = POJORegistry{
+ pojoRegistry = &POJORegistry{
j2g: make(map[string]string),
- registry: make(map[string]structInfo),
+ registry: make(map[string]*structInfo),
}
pojoType = reflect.TypeOf((*POJO)(nil)).Elem()
javaEnumType = reflect.TypeOf((*POJOEnum)(nil)).Elem()
@@ -205,8 +205,8 @@
clsDef.buffer = append(bHeader, bBody...)
structInfo.index = len(pojoRegistry.classInfoList)
- pojoRegistry.classInfoList = append(pojoRegistry.classInfoList, clsDef)
- pojoRegistry.registry[structInfo.goName] = structInfo
+ pojoRegistry.classInfoList = append(pojoRegistry.classInfoList, &clsDef)
+ pojoRegistry.registry[structInfo.goName] = &structInfo
return structInfo.index
}
@@ -307,8 +307,8 @@
c = classInfo{javaName: t.javaName, fieldNameList: l}
c.buffer = append(c.buffer, b[:]...)
t.index = len(pojoRegistry.classInfoList)
- pojoRegistry.classInfoList = append(pojoRegistry.classInfoList, c)
- pojoRegistry.registry[t.goName] = t
+ pojoRegistry.classInfoList = append(pojoRegistry.classInfoList, &c)
+ pojoRegistry.registry[t.goName] = &t
i = t.index
} else {
i = -1
@@ -319,23 +319,32 @@
// check if go struct name @goName has been registered or not.
func checkPOJORegistry(goName string) (int, bool) {
+ s, ok := loadPOJORegistry(goName)
+ if !ok {
+ return -1, false
+ }
+ return s.index, true
+}
+
+// load struct info if go struct name @goName has been registered or not.
+func loadPOJORegistry(goName string) (*structInfo, bool) {
var (
ok bool
- s structInfo
+ s *structInfo
)
pojoRegistry.RLock()
s, ok = pojoRegistry.registry[goName]
pojoRegistry.RUnlock()
- return s.index, ok
+ return s, ok
}
// @typeName is class's java name
-func getStructInfo(javaName string) (structInfo, bool) {
+func getStructInfo(javaName string) (*structInfo, bool) {
var (
ok bool
g string
- s structInfo
+ s *structInfo
)
pojoRegistry.RLock()
@@ -348,12 +357,12 @@
return s, ok
}
-func getStructDefByIndex(idx int) (reflect.Type, classInfo, error) {
+func getStructDefByIndex(idx int) (reflect.Type, *classInfo, error) {
var (
ok bool
clsName string
- cls classInfo
- s structInfo
+ cls *classInfo
+ s *structInfo
)
pojoRegistry.RLock()
@@ -380,7 +389,7 @@
func createInstance(goName string) interface{} {
var (
ok bool
- s structInfo
+ s *structInfo
)
pojoRegistry.RLock()
diff --git a/serialize.go b/serialize.go
index 2584d10..b57702b 100644
--- a/serialize.go
+++ b/serialize.go
@@ -37,7 +37,7 @@
type Serializer interface {
EncObject(*Encoder, POJO) error
- DecObject(*Decoder, reflect.Type, classInfo) (interface{}, error)
+ DecObject(*Decoder, reflect.Type, *classInfo) (interface{}, error)
}
var serializerMap = make(map[string]Serializer, 16)
@@ -53,7 +53,7 @@
type IntegerSerializer struct{}
-func (IntegerSerializer) DecObject(d *Decoder, typ reflect.Type, cls classInfo) (interface{}, error) {
+func (IntegerSerializer) DecObject(d *Decoder, typ reflect.Type, cls *classInfo) (interface{}, error) {
bigInt, err := d.decInstance(typ, cls)
if err != nil {
return nil, err
@@ -88,7 +88,7 @@
return e.encObject(decimal)
}
-func (DecimalSerializer) DecObject(d *Decoder, typ reflect.Type, cls classInfo) (interface{}, error) {
+func (DecimalSerializer) DecObject(d *Decoder, typ reflect.Type, cls *classInfo) (interface{}, error) {
dec, err := d.decInstance(typ, cls)
if err != nil {
return nil, err