Cache model struct for less GC

This commit is contained in:
Jinzhu 2013-11-17 08:55:37 +08:00
parent 9a1c0d956d
commit 88917aa2ef
1 changed files with 47 additions and 28 deletions

View File

@ -8,6 +8,12 @@ import (
"time" "time"
) )
var modelFieldMap map[string][]reflect.StructField
func init() {
modelFieldMap = map[string][]reflect.StructField{}
}
type Model struct { type Model struct {
data interface{} data interface{}
do *Do do *Do
@ -39,21 +45,35 @@ func (m *Model) primaryKeyDb() string {
return toSnake(m.primaryKey()) return toSnake(m.primaryKey())
} }
func getStructs(typ reflect.Type) (fs []reflect.StructField) {
name := typ.Name()
if fs = modelFieldMap[name]; fs != nil {
return
}
for i := 0; i < typ.NumField(); i++ {
p := typ.Field(i)
if !p.Anonymous && ast.IsExported(p.Name) {
fs = append(fs, p)
}
}
modelFieldMap[name] = fs
return
}
func (m *Model) fields(operation string) (fields []*Field) { func (m *Model) fields(operation string) (fields []*Field) {
indirect_value := m.reflectData() indirect_value := m.reflectData()
if !indirect_value.IsValid() { if !indirect_value.IsValid() {
return return
} }
typ := indirect_value.Type() for _, filed_struct := range getStructs(indirect_value.Type()) {
for i := 0; i < typ.NumField(); i++ {
p := typ.Field(i)
if !p.Anonymous && ast.IsExported(p.Name) {
var field Field var field Field
field.Name = p.Name field.Name = filed_struct.Name
field.dbName = toSnake(p.Name) field.dbName = toSnake(filed_struct.Name)
field.isPrimaryKey = m.primaryKeyDb() == field.dbName field.isPrimaryKey = m.primaryKeyDb() == field.dbName
value := indirect_value.FieldByName(p.Name) value := indirect_value.FieldByName(filed_struct.Name)
field.model = m field.model = m
if time_value, is_time := value.Interface().(time.Time); is_time { if time_value, is_time := value.Interface().(time.Time); is_time {
@ -72,13 +92,12 @@ func (m *Model) fields(operation string) (fields []*Field) {
} }
} }
field.structField = p field.structField = filed_struct
field.reflectValue = value field.reflectValue = value
field.Value = value.Interface() field.Value = value.Interface()
field.parseAssociation() field.parseAssociation()
fields = append(fields, &field) fields = append(fields, &field)
} }
}
return return
} }