Add sync.Pool
This commit is contained in:
		
							parent
							
								
									fb52b97363
								
							
						
					
					
						commit
						07f0438435
					
				
							
								
								
									
										8
									
								
								scan.go
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								scan.go
									
									
									
									
									
								
							@ -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
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
				
			|||||||
@ -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 {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user