Phase 1 optimization complete, Phase 2 ( Warm liquid goo phase ) commencing

Still looking good

```

benchmark                                               old ns/op     new ns/op     delta
BenchmarkFieldSuccess-4                                 167           119           -28.74%
BenchmarkFieldFailure-4                                 701           653           -6.85%
BenchmarkFieldDiveSuccess-4                             2937          2488          -15.29%
BenchmarkFieldDiveFailure-4                             3536          3059          -13.49%
BenchmarkFieldCustomTypeSuccess-4                       341           292           -14.37%
BenchmarkFieldCustomTypeFailure-4                       679           679           +0.00%
BenchmarkFieldOrTagSuccess-4                            1157          1146          -0.95%
BenchmarkFieldOrTagFailure-4                            1109          1063          -4.15%
BenchmarkStructLevelValidationSuccess-4                 694           559           -19.45%
BenchmarkStructLevelValidationFailure-4                 1311          551           -57.97%
BenchmarkStructSimpleCustomTypeSuccess-4                894           641           -28.30%
BenchmarkStructSimpleCustomTypeFailure-4                1496          1302          -12.97%
BenchmarkStructPartialSuccess-4                         1229          1071          -12.86%
BenchmarkStructPartialFailure-4                         1838          1685          -8.32%
BenchmarkStructExceptSuccess-4                          961           927           -3.54%
BenchmarkStructExceptFailure-4                          1218          1068          -12.32%
BenchmarkStructSimpleCrossFieldSuccess-4                954           779           -18.34%
BenchmarkStructSimpleCrossFieldFailure-4                1569          1405          -10.45%
BenchmarkStructSimpleCrossStructCrossFieldSuccess-4     1588          1299          -18.20%
BenchmarkStructSimpleCrossStructCrossFieldFailure-4     2217          1917          -13.53%
BenchmarkStructSimpleSuccess-4                          925           519           -43.89%
BenchmarkStructSimpleFailure-4                          1650          1323          -19.82%
BenchmarkStructSimpleSuccessParallel-4                  261           149           -42.91%
BenchmarkStructSimpleFailureParallel-4                  758           543           -28.36%
BenchmarkStructComplexSuccess-4                         5868          3387          -42.28%
BenchmarkStructComplexFailure-4                         10767         8498          -21.07%
BenchmarkStructComplexSuccessParallel-4                 1559          1114          -28.54%
BenchmarkStructComplexFailureParallel-4                 3747          3163          -15.59%

```
pull/252/head
joeybloggs 8 years ago
parent 210684a828
commit 330b12dacd
  1. 39
      validator.go
  2. 30
      validator_test.go

@ -622,11 +622,6 @@ func (v *Validate) traverseField(topStruct reflect.Value, currentStruct reflect.
return return
} }
// if we get here tag length is zero and we can leave
if kind == reflect.Invalid {
return
}
case reflect.Struct: case reflect.Struct:
typ = current.Type() typ = current.Type()
@ -705,40 +700,6 @@ OUTER:
for { for {
if !ct.isOrVal {
// if we get here, no valid 'or' value, but more tags
ns := errPrefix + cf.Name
if ct.hasAlias {
errs[ns] = &FieldError{
FieldNamespace: ns,
NameNamespace: nsPrefix + cf.AltName,
Name: cf.AltName,
Field: cf.Name,
Tag: ct.aliasTag,
ActualTag: ct.actualAliasTag,
Value: current.Interface(),
Type: typ,
Kind: kind,
}
} else {
errs[errPrefix+cf.Name] = &FieldError{
FieldNamespace: ns,
NameNamespace: nsPrefix + cf.AltName,
Name: cf.AltName,
Field: cf.Name,
Tag: errTag[1:],
ActualTag: errTag[1:],
Value: current.Interface(),
Type: typ,
Kind: kind,
}
}
continue OUTER
}
if ct.fn(v, topStruct, currentStruct, current, typ, kind, ct.param) { if ct.fn(v, topStruct, currentStruct, current, typ, kind, ct.param) {
// drain rest of the 'or' values, then continue or leave // drain rest of the 'or' values, then continue or leave

@ -2370,6 +2370,9 @@ func TestSliceMapArrayChanFuncPtrInterfaceRequiredValidation(t *testing.T) {
errs = validate.Field(iface, "") errs = validate.Field(iface, "")
Equal(t, errs, nil) Equal(t, errs, nil)
errs = validate.FieldWithValue(nil, iface, "")
Equal(t, errs, nil)
var f func(string) var f func(string)
errs = validate.Field(f, "required") errs = validate.Field(f, "required")
@ -5787,3 +5790,30 @@ func TestCustomFieldName(t *testing.T) {
Equal(t, errs["A.D"].Name, "D") Equal(t, errs["A.D"].Name, "D")
Equal(t, errs["A.E"].Name, "E") Equal(t, errs["A.E"].Name, "E")
} }
func TestMutipleRecursiveExtractStructCache(t *testing.T) {
type Recursive struct {
Field *string `validate:"exists,required,len=5,ne=string"`
}
var test Recursive
current := reflect.ValueOf(test)
name := "Recursive"
proceed := make(chan struct{})
sc := validate.extractStructCache(current, name)
ptr := fmt.Sprintf("%p", sc)
for i := 0; i < 100; i++ {
go func() {
<-proceed
sc := validate.extractStructCache(current, name)
Equal(t, ptr, fmt.Sprintf("%p", sc))
}()
}
close(proceed)
}

Loading…
Cancel
Save