From 330b12dacd1fa5dfda41fb7c4e620312cb08d07c Mon Sep 17 00:00:00 2001 From: joeybloggs Date: Mon, 11 Jul 2016 11:39:04 -0400 Subject: [PATCH] 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% ``` --- validator.go | 39 --------------------------------------- validator_test.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 39 deletions(-) diff --git a/validator.go b/validator.go index 096365d..2ab85a3 100644 --- a/validator.go +++ b/validator.go @@ -622,11 +622,6 @@ func (v *Validate) traverseField(topStruct reflect.Value, currentStruct reflect. return } - // if we get here tag length is zero and we can leave - if kind == reflect.Invalid { - return - } - case reflect.Struct: typ = current.Type() @@ -705,40 +700,6 @@ OUTER: 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) { // drain rest of the 'or' values, then continue or leave diff --git a/validator_test.go b/validator_test.go index 6d4cadd..7c2719c 100644 --- a/validator_test.go +++ b/validator_test.go @@ -2370,6 +2370,9 @@ func TestSliceMapArrayChanFuncPtrInterfaceRequiredValidation(t *testing.T) { errs = validate.Field(iface, "") Equal(t, errs, nil) + errs = validate.FieldWithValue(nil, iface, "") + Equal(t, errs, nil) + var f func(string) 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.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) +}