Skip to content

Commit a32ef92

Browse files
Dean KarnDean Karn
authored andcommitted
Merge pull request #158 from bluesuncorp/v6-development
Backport v7 updates
2 parents 9a93f01 + 19d8904 commit a32ef92

File tree

6 files changed

+554
-159
lines changed

6 files changed

+554
-159
lines changed

README.md

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -192,24 +192,28 @@ NOTE: allocations for structs are up from v5, however ns/op for parallel operati
192192
It was a decicion not to cache struct info because although it reduced allocation to v5 levels, it
193193
hurt parallel performance too much.
194194
```go
195-
$ go test -cpu=4 -bench=. -benchmem=true
195+
go test -cpu=4 -bench=. -benchmem=true
196196
PASS
197-
BenchmarkFieldSuccess-4 5000000 318 ns/op 16 B/op 1 allocs/op
198-
BenchmarkFieldFailure-4 5000000 316 ns/op 16 B/op 1 allocs/op
199-
BenchmarkFieldCustomTypeSuccess-4 3000000 492 ns/op 32 B/op 2 allocs/op
200-
BenchmarkFieldCustomTypeFailure-4 2000000 843 ns/op 416 B/op 6 allocs/op
201-
BenchmarkFieldOrTagSuccess-4 500000 2384 ns/op 20 B/op 2 allocs/op
202-
BenchmarkFieldOrTagFailure-4 1000000 1295 ns/op 384 B/op 6 allocs/op
203-
BenchmarkStructSimpleSuccess-4 1000000 1175 ns/op 24 B/op 3 allocs/op
204-
BenchmarkStructSimpleFailure-4 1000000 1822 ns/op 529 B/op 11 allocs/op
205-
BenchmarkStructSimpleCustomTypeSuccess-4 1000000 1302 ns/op 56 B/op 5 allocs/op
206-
BenchmarkStructSimpleCustomTypeFailure-4 1000000 1847 ns/op 577 B/op 13 allocs/op
207-
BenchmarkStructSimpleSuccessParallel-4 5000000 339 ns/op 24 B/op 3 allocs/op
208-
BenchmarkStructSimpleFailureParallel-4 2000000 733 ns/op 529 B/op 11 allocs/op
209-
BenchmarkStructComplexSuccess-4 200000 7104 ns/op 368 B/op 30 allocs/op
210-
BenchmarkStructComplexFailure-4 100000 11996 ns/op 2861 B/op 72 allocs/op
211-
BenchmarkStructComplexSuccessParallel-4 1000000 2252 ns/op 368 B/op 30 allocs/op
212-
BenchmarkStructComplexFailureParallel-4 300000 4691 ns/op 2862 B/op 72 allocs/op
197+
BenchmarkFieldSuccess-4 5000000 337 ns/op 16 B/op 1 allocs/op
198+
BenchmarkFieldFailure-4 5000000 331 ns/op 16 B/op 1 allocs/op
199+
BenchmarkFieldCustomTypeSuccess-4 3000000 497 ns/op 32 B/op 2 allocs/op
200+
BenchmarkFieldCustomTypeFailure-4 2000000 842 ns/op 416 B/op 6 allocs/op
201+
BenchmarkFieldOrTagSuccess-4 500000 2432 ns/op 20 B/op 2 allocs/op
202+
BenchmarkFieldOrTagFailure-4 1000000 1323 ns/op 384 B/op 6 allocs/op
203+
BenchmarkStructSimpleCustomTypeSuccess-4 1000000 1409 ns/op 56 B/op 5 allocs/op
204+
BenchmarkStructSimpleCustomTypeFailure-4 1000000 1876 ns/op 577 B/op 13 allocs/op
205+
BenchmarkStructPartialSuccess-4 1000000 1438 ns/op 384 B/op 13 allocs/op
206+
BenchmarkStructPartialFailure-4 1000000 2040 ns/op 785 B/op 18 allocs/op
207+
BenchmarkStructExceptSuccess-4 1000000 1000 ns/op 368 B/op 11 allocs/op
208+
BenchmarkStructExceptFailure-4 1000000 1431 ns/op 384 B/op 13 allocs/op
209+
BenchmarkStructSimpleSuccess-4 1000000 1375 ns/op 24 B/op 3 allocs/op
210+
BenchmarkStructSimpleFailure-4 1000000 1893 ns/op 529 B/op 11 allocs/op
211+
BenchmarkStructSimpleSuccessParallel-4 5000000 362 ns/op 24 B/op 3 allocs/op
212+
BenchmarkStructSimpleFailureParallel-4 2000000 883 ns/op 529 B/op 11 allocs/op
213+
BenchmarkStructComplexSuccess-4 200000 8237 ns/op 368 B/op 30 allocs/op
214+
BenchmarkStructComplexFailure-4 100000 12617 ns/op 2861 B/op 72 allocs/op
215+
BenchmarkStructComplexSuccessParallel-4 1000000 2398 ns/op 368 B/op 30 allocs/op
216+
BenchmarkStructComplexFailureParallel-4 300000 5733 ns/op 2862 B/op 72 allocs/op
213217
```
214218

215219
How to Contribute

baked_in.go

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"net"
66
"net/url"
77
"reflect"
8-
"strconv"
98
"strings"
109
"time"
1110
"unicode/utf8"
@@ -902,39 +901,3 @@ func hasMaxOf(topStruct reflect.Value, currentStruct reflect.Value, field reflec
902901

903902
return isLte(topStruct, currentStruct, field, fieldType, fieldKind, param)
904903
}
905-
906-
// asInt retuns the parameter as a int64
907-
// or panics if it can't convert
908-
func asInt(param string) int64 {
909-
910-
i, err := strconv.ParseInt(param, 0, 64)
911-
panicIf(err)
912-
913-
return i
914-
}
915-
916-
// asUint returns the parameter as a uint64
917-
// or panics if it can't convert
918-
func asUint(param string) uint64 {
919-
920-
i, err := strconv.ParseUint(param, 0, 64)
921-
panicIf(err)
922-
923-
return i
924-
}
925-
926-
// asFloat returns the parameter as a float64
927-
// or panics if it can't convert
928-
func asFloat(param string) float64 {
929-
930-
i, err := strconv.ParseFloat(param, 64)
931-
panicIf(err)
932-
933-
return i
934-
}
935-
936-
func panicIf(err error) {
937-
if err != nil {
938-
panic(err.Error())
939-
}
940-
}

benchmarks_test.go

Lines changed: 92 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -62,34 +62,6 @@ func BenchmarkFieldOrTagFailure(b *testing.B) {
6262
}
6363
}
6464

65-
func BenchmarkStructSimpleSuccess(b *testing.B) {
66-
67-
type Foo struct {
68-
StringValue string `validate:"min=5,max=10"`
69-
IntValue int `validate:"min=5,max=10"`
70-
}
71-
72-
validFoo := &Foo{StringValue: "Foobar", IntValue: 7}
73-
74-
for n := 0; n < b.N; n++ {
75-
validate.Struct(validFoo)
76-
}
77-
}
78-
79-
func BenchmarkStructSimpleFailure(b *testing.B) {
80-
81-
type Foo struct {
82-
StringValue string `validate:"min=5,max=10"`
83-
IntValue int `validate:"min=5,max=10"`
84-
}
85-
86-
invalidFoo := &Foo{StringValue: "Fo", IntValue: 3}
87-
88-
for n := 0; n < b.N; n++ {
89-
validate.Struct(invalidFoo)
90-
}
91-
}
92-
9365
func BenchmarkStructSimpleCustomTypeSuccess(b *testing.B) {
9466

9567
customTypes := map[reflect.Type]CustomTypeFunc{}
@@ -136,6 +108,98 @@ func BenchmarkStructSimpleCustomTypeFailure(b *testing.B) {
136108
}
137109
}
138110

111+
func BenchmarkStructPartialSuccess(b *testing.B) {
112+
113+
type Test struct {
114+
Name string `validate:"required"`
115+
NickName string `validate:"required"`
116+
}
117+
118+
test := &Test{
119+
Name: "Joey Bloggs",
120+
}
121+
122+
for n := 0; n < b.N; n++ {
123+
validate.StructPartial(test, "Name")
124+
}
125+
}
126+
127+
func BenchmarkStructPartialFailure(b *testing.B) {
128+
129+
type Test struct {
130+
Name string `validate:"required"`
131+
NickName string `validate:"required"`
132+
}
133+
134+
test := &Test{
135+
Name: "Joey Bloggs",
136+
}
137+
138+
for n := 0; n < b.N; n++ {
139+
validate.StructPartial(test, "NickName")
140+
}
141+
}
142+
143+
func BenchmarkStructExceptSuccess(b *testing.B) {
144+
145+
type Test struct {
146+
Name string `validate:"required"`
147+
NickName string `validate:"required"`
148+
}
149+
150+
test := &Test{
151+
Name: "Joey Bloggs",
152+
}
153+
154+
for n := 0; n < b.N; n++ {
155+
validate.StructPartial(test, "Nickname")
156+
}
157+
}
158+
159+
func BenchmarkStructExceptFailure(b *testing.B) {
160+
161+
type Test struct {
162+
Name string `validate:"required"`
163+
NickName string `validate:"required"`
164+
}
165+
166+
test := &Test{
167+
Name: "Joey Bloggs",
168+
}
169+
170+
for n := 0; n < b.N; n++ {
171+
validate.StructPartial(test, "Name")
172+
}
173+
}
174+
175+
func BenchmarkStructSimpleSuccess(b *testing.B) {
176+
177+
type Foo struct {
178+
StringValue string `validate:"min=5,max=10"`
179+
IntValue int `validate:"min=5,max=10"`
180+
}
181+
182+
validFoo := &Foo{StringValue: "Foobar", IntValue: 7}
183+
184+
for n := 0; n < b.N; n++ {
185+
validate.Struct(validFoo)
186+
}
187+
}
188+
189+
func BenchmarkStructSimpleFailure(b *testing.B) {
190+
191+
type Foo struct {
192+
StringValue string `validate:"min=5,max=10"`
193+
IntValue int `validate:"min=5,max=10"`
194+
}
195+
196+
invalidFoo := &Foo{StringValue: "Fo", IntValue: 3}
197+
198+
for n := 0; n < b.N; n++ {
199+
validate.Struct(invalidFoo)
200+
}
201+
}
202+
139203
func BenchmarkStructSimpleSuccessParallel(b *testing.B) {
140204

141205
type Foo struct {

util.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package validator
2+
3+
import (
4+
"reflect"
5+
"strconv"
6+
)
7+
8+
const (
9+
namespaceSeparator = "."
10+
leftBracket = "["
11+
rightBracket = "]"
12+
)
13+
14+
func (v *Validate) extractType(current reflect.Value) (reflect.Value, reflect.Kind) {
15+
16+
switch current.Kind() {
17+
case reflect.Ptr:
18+
19+
if current.IsNil() {
20+
return current, reflect.Ptr
21+
}
22+
23+
return v.extractType(current.Elem())
24+
25+
case reflect.Interface:
26+
27+
if current.IsNil() {
28+
return current, reflect.Interface
29+
}
30+
31+
return v.extractType(current.Elem())
32+
33+
case reflect.Invalid:
34+
return current, reflect.Invalid
35+
36+
default:
37+
38+
if v.config.hasCustomFuncs {
39+
if fn, ok := v.config.CustomTypeFuncs[current.Type()]; ok {
40+
return v.extractType(reflect.ValueOf(fn(current)))
41+
}
42+
}
43+
44+
return current, current.Kind()
45+
}
46+
}
47+
48+
// asInt retuns the parameter as a int64
49+
// or panics if it can't convert
50+
func asInt(param string) int64 {
51+
52+
i, err := strconv.ParseInt(param, 0, 64)
53+
panicIf(err)
54+
55+
return i
56+
}
57+
58+
// asUint returns the parameter as a uint64
59+
// or panics if it can't convert
60+
func asUint(param string) uint64 {
61+
62+
i, err := strconv.ParseUint(param, 0, 64)
63+
panicIf(err)
64+
65+
return i
66+
}
67+
68+
// asFloat returns the parameter as a float64
69+
// or panics if it can't convert
70+
func asFloat(param string) float64 {
71+
72+
i, err := strconv.ParseFloat(param, 64)
73+
panicIf(err)
74+
75+
return i
76+
}
77+
78+
func panicIf(err error) {
79+
if err != nil {
80+
panic(err.Error())
81+
}
82+
}

0 commit comments

Comments
 (0)