Add sync.Pool

This commit is contained in:
Jinzhu 2022-02-14 19:31:32 +08:00
parent fb52b97363
commit 07f0438435
2 changed files with 37 additions and 7 deletions

View File

@ -55,11 +55,13 @@ func (db *DB) scanIntoStruct(sch *schema.Schema, rows *sql.Rows, reflectValue re
if sch == nil { if sch == nil {
values[idx] = reflectValue.Interface() values[idx] = reflectValue.Interface()
} else if field := sch.LookUpField(column); field != nil && field.Readable { } else if field := sch.LookUpField(column); field != nil && field.Readable {
values[idx] = reflect.New(reflect.PtrTo(field.IndirectFieldType)).Interface() values[idx] = field.NewScanValue()
} else if names := strings.Split(column, "__"); len(names) > 1 { defer field.ReleaseScanValue(values[idx])
} else if names := strings.Split(column, "__"); len(names) > 2 {
if rel, ok := sch.Relationships.Relations[names[0]]; ok { if rel, ok := sch.Relationships.Relations[names[0]]; ok {
if field := rel.FieldSchema.LookUpField(strings.Join(names[1:], "__")); field != nil && field.Readable { if field := rel.FieldSchema.LookUpField(strings.Join(names[1:], "__")); field != nil && field.Readable {
values[idx] = reflect.New(reflect.PtrTo(field.IndirectFieldType)).Interface() values[idx] = field.NewScanValue()
defer field.ReleaseScanValue(values[idx])
continue continue
} }
} }

View File

@ -84,6 +84,8 @@ type Field struct {
ReflectValueOf func(context.Context, reflect.Value) reflect.Value ReflectValueOf func(context.Context, reflect.Value) reflect.Value
ValueOf func(context.Context, reflect.Value) (value interface{}, zero bool) ValueOf func(context.Context, reflect.Value) (value interface{}, zero bool)
Set func(context.Context, reflect.Value, interface{}) error Set func(context.Context, reflect.Value, interface{}) error
NewScanValue func() interface{}
ReleaseScanValue func(interface{})
} }
// ParseField parses reflect.StructField to Field // ParseField parses reflect.StructField to Field
@ -412,13 +414,39 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field {
return field return field
} }
var (
bytesPool = sync.Pool{
New: func() interface{} {
bs := make([]byte, 0, 10)
return &bs
},
}
bytesPoolReleaser = func(v interface{}) {
bs := v.(*[]byte)
*bs = (*bs)[:0]
if string(*bs) != "" {
fmt.Println(string(*bs))
}
bytesPool.Put(bs)
}
)
// create valuer, setter when parse struct // create valuer, setter when parse struct
func (field *Field) setupValuerAndSetter() { func (field *Field) setupValuerAndSetter() {
// ValueOf returns field's value and if it is zero // Setup NewScanValue
switch field.DataType {
case Bytes, String:
field.NewScanValue = bytesPool.Get
field.ReleaseScanValue = bytesPoolReleaser
default:
field.NewScanValue = func() interface{} {
return reflect.New(reflect.PtrTo(field.IndirectFieldType)).Interface()
}
field.ReleaseScanValue = func(interface{}) {
}
}
// if vr, ok := fv.(GormFieldValuer); ok { // ValueOf returns field's value and if it is zero
// fv, zero = vr.GormFieldValue(ctx, field)
// }
field.ValueOf = func(ctx context.Context, v reflect.Value) (interface{}, bool) { field.ValueOf = func(ctx context.Context, v reflect.Value) (interface{}, bool) {
v = reflect.Indirect(v) v = reflect.Indirect(v)
for _, fieldIdx := range field.StructField.Index { for _, fieldIdx := range field.StructField.Index {