Update Error Pool

* made error pool per validator instance to reduce contention is
  multiple validators are in play.
pull/169/head
joeybloggs 9 years ago
parent 70cb087d5a
commit 0b51279b05
  1. 34
      validator.go

@ -41,14 +41,8 @@ var (
timeType = reflect.TypeOf(time.Time{}) timeType = reflect.TypeOf(time.Time{})
timePtrType = reflect.TypeOf(&time.Time{}) timePtrType = reflect.TypeOf(&time.Time{})
emptyStructPtr = new(struct{}) emptyStructPtr = new(struct{})
errsPool = &sync.Pool{New: newValidationErrors}
) )
// returns new ValidationErrors to the pool
func newValidationErrors() interface{} {
return ValidationErrors{}
}
type cachedTag struct { type cachedTag struct {
isOmitEmpty bool isOmitEmpty bool
diveTag string diveTag string
@ -89,6 +83,7 @@ type Validate struct {
hasCustomFuncs bool hasCustomFuncs bool
hasAliasValidators bool hasAliasValidators bool
tagsCache *tagCacheMap tagsCache *tagCacheMap
errsPool *sync.Pool
} }
// Config contains the options that a Validator instance will use. // Config contains the options that a Validator instance will use.
@ -149,7 +144,12 @@ func New(config *Config) *Validate {
// if config.CustomTypeFuncs != nil && len(config.CustomTypeFuncs) > 0 { // if config.CustomTypeFuncs != nil && len(config.CustomTypeFuncs) > 0 {
// config.hasCustomFuncs = true // config.hasCustomFuncs = true
// } // }
v := &Validate{tagName: config.TagName, tagsCache: &tagCacheMap{m: map[string]*cachedTag{}}} v := &Validate{
tagName: config.TagName,
tagsCache: &tagCacheMap{m: map[string]*cachedTag{}},
errsPool: &sync.Pool{New: func() interface{} {
return ValidationErrors{}
}}}
if len(v.aliasValidators) == 0 { if len(v.aliasValidators) == 0 {
// must copy validators for separate validations to be used in each validator instance // must copy validators for separate validations to be used in each validator instance
@ -232,13 +232,13 @@ func (v *Validate) RegisterAliasValidation(alias, tags string) {
// validate Array, Slice and maps fields which may contain more than one error // validate Array, Slice and maps fields which may contain more than one error
func (v *Validate) Field(field interface{}, tag string) error { func (v *Validate) Field(field interface{}, tag string) error {
errs := errsPool.Get().(ValidationErrors) errs := v.errsPool.Get().(ValidationErrors)
fieldVal := reflect.ValueOf(field) fieldVal := reflect.ValueOf(field)
v.traverseField(fieldVal, fieldVal, fieldVal, blank, errs, false, tag, blank, false, false, nil) v.traverseField(fieldVal, fieldVal, fieldVal, blank, errs, false, tag, blank, false, false, nil)
if len(errs) == 0 { if len(errs) == 0 {
errsPool.Put(errs) v.errsPool.Put(errs)
return nil return nil
} }
@ -251,13 +251,13 @@ func (v *Validate) Field(field interface{}, tag string) error {
// validate Array, Slice and maps fields which may contain more than one error // validate Array, Slice and maps fields which may contain more than one error
func (v *Validate) FieldWithValue(val interface{}, field interface{}, tag string) error { func (v *Validate) FieldWithValue(val interface{}, field interface{}, tag string) error {
errs := errsPool.Get().(ValidationErrors) errs := v.errsPool.Get().(ValidationErrors)
topVal := reflect.ValueOf(val) topVal := reflect.ValueOf(val)
v.traverseField(topVal, topVal, reflect.ValueOf(field), blank, errs, false, tag, blank, false, false, nil) v.traverseField(topVal, topVal, reflect.ValueOf(field), blank, errs, false, tag, blank, false, false, nil)
if len(errs) == 0 { if len(errs) == 0 {
errsPool.Put(errs) v.errsPool.Put(errs)
return nil return nil
} }
@ -309,12 +309,12 @@ func (v *Validate) StructPartial(current interface{}, fields ...string) error {
} }
} }
errs := errsPool.Get().(ValidationErrors) errs := v.errsPool.Get().(ValidationErrors)
v.tranverseStruct(sv, sv, sv, blank, errs, true, len(m) != 0, false, m) v.tranverseStruct(sv, sv, sv, blank, errs, true, len(m) != 0, false, m)
if len(errs) == 0 { if len(errs) == 0 {
errsPool.Put(errs) v.errsPool.Put(errs)
return nil return nil
} }
@ -335,12 +335,12 @@ func (v *Validate) StructExcept(current interface{}, fields ...string) error {
m[name+"."+key] = emptyStructPtr m[name+"."+key] = emptyStructPtr
} }
errs := errsPool.Get().(ValidationErrors) errs := v.errsPool.Get().(ValidationErrors)
v.tranverseStruct(sv, sv, sv, blank, errs, true, len(m) != 0, true, m) v.tranverseStruct(sv, sv, sv, blank, errs, true, len(m) != 0, true, m)
if len(errs) == 0 { if len(errs) == 0 {
errsPool.Put(errs) v.errsPool.Put(errs)
return nil return nil
} }
@ -352,13 +352,13 @@ func (v *Validate) StructExcept(current interface{}, fields ...string) error {
// You will need to assert the error if it's not nil i.e. err.(validator.ValidationErrors) to access the map of errors. // You will need to assert the error if it's not nil i.e. err.(validator.ValidationErrors) to access the map of errors.
func (v *Validate) Struct(current interface{}) error { func (v *Validate) Struct(current interface{}) error {
errs := errsPool.Get().(ValidationErrors) errs := v.errsPool.Get().(ValidationErrors)
sv := reflect.ValueOf(current) sv := reflect.ValueOf(current)
v.tranverseStruct(sv, sv, sv, blank, errs, true, false, false, nil) v.tranverseStruct(sv, sv, sv, blank, errs, true, false, false, nil)
if len(errs) == 0 { if len(errs) == 0 {
errsPool.Put(errs) v.errsPool.Put(errs)
return nil return nil
} }

Loading…
Cancel
Save