perf updates all around!

pull/256/head
joeybloggs 8 years ago
parent 560bff6526
commit 98dee40973
  1. 51
      validator.go
  2. 10
      validator_instance.go
  3. 8
      validator_test.go

@ -3,6 +3,7 @@ package validator
import ( import (
"fmt" "fmt"
"reflect" "reflect"
"strconv"
) )
const ( const (
@ -20,6 +21,7 @@ type validate struct {
isPartial bool isPartial bool
hasExcludes bool hasExcludes bool
includeExclude map[string]struct{} // reset only if StructPartial or StructExcept are called, no need otherwise includeExclude map[string]struct{} // reset only if StructPartial or StructExcept are called, no need otherwise
misc []byte
// StructLevel & FieldLevel fields // StructLevel & FieldLevel fields
slflParent reflect.Value slflParent reflect.Value
@ -203,13 +205,48 @@ OUTER:
switch kind { switch kind {
case reflect.Slice, reflect.Array: case reflect.Slice, reflect.Array:
var nm string
// TODO: cache pool &cField
for i := 0; i < current.Len(); i++ { for i := 0; i < current.Len(); i++ {
v.traverseField(parent, current.Index(i), ns, structNs, &cField{Name: fmt.Sprintf(arrayIndexFieldName, cf.Name, i), AltName: fmt.Sprintf(arrayIndexFieldName, cf.AltName, i)}, ct)
v.misc = append(v.misc[0:0], cf.Name...)
v.misc = append(v.misc, '[')
v.misc = strconv.AppendInt(v.misc, int64(i), 10)
v.misc = append(v.misc, ']')
nm = string(v.misc)
v.misc = append(v.misc[0:0], cf.AltName...)
v.misc = append(v.misc, '[')
v.misc = strconv.AppendInt(v.misc, int64(i), 10)
v.misc = append(v.misc, ']')
v.traverseField(parent, current.Index(i), ns, structNs, &cField{Name: nm, AltName: string(v.misc)}, ct)
} }
case reflect.Map: case reflect.Map:
var nm string
var pv string
for _, key := range current.MapKeys() { for _, key := range current.MapKeys() {
v.traverseField(parent, current.MapIndex(key), ns, structNs, &cField{Name: fmt.Sprintf(mapIndexFieldName, cf.Name, key.Interface()), AltName: fmt.Sprintf(mapIndexFieldName, cf.AltName, key.Interface())}, ct)
pv = fmt.Sprintf("%v", key.Interface())
v.misc = append(v.misc[0:0], cf.Name...)
v.misc = append(v.misc, '[')
v.misc = append(v.misc, pv...)
v.misc = append(v.misc, ']')
nm = string(v.misc)
v.misc = append(v.misc[0:0], cf.AltName...)
v.misc = append(v.misc, '[')
v.misc = append(v.misc, pv...)
v.misc = append(v.misc, ']')
v.traverseField(parent, current.MapIndex(key), ns, structNs, &cField{Name: nm, AltName: string(v.misc)}, ct)
} }
default: default:
@ -222,7 +259,7 @@ OUTER:
case typeOr: case typeOr:
errTag := make([]byte, 0, 64) v.misc = v.misc[0:0]
for { for {
@ -248,8 +285,8 @@ OUTER:
} }
} }
errTag = append(errTag, '|') v.misc = append(v.misc, '|')
errTag = append(errTag, ct.tag...) v.misc = append(v.misc, ct.tag...)
if ct.next == nil { if ct.next == nil {
// if we get here, no valid 'or' value and no more tags // if we get here, no valid 'or' value and no more tags
@ -275,8 +312,8 @@ OUTER:
v.errs = append(v.errs, v.errs = append(v.errs,
&fieldError{ &fieldError{
tag: string(errTag)[1:], tag: string(v.misc)[1:],
actualTag: string(errTag)[1:], actualTag: string(v.misc)[1:],
ns: string(append(ns, cf.AltName...)), ns: string(append(ns, cf.AltName...)),
structNs: string(append(structNs, cf.Name...)), structNs: string(append(structNs, cf.Name...)),
field: cf.AltName, field: cf.AltName,

@ -89,8 +89,11 @@ func New() *Validate {
v.pool = &sync.Pool{ v.pool = &sync.Pool{
New: func() interface{} { New: func() interface{} {
return &validate{ return &validate{
v: v, v: v,
errs: make(ValidationErrors, 0, 4), errs: make(ValidationErrors, 0, 4),
ns: make([]byte, 0, 64),
actualNs: make([]byte, 0, 64),
misc: make([]byte, 32),
} }
}, },
} }
@ -209,9 +212,10 @@ func (v *Validate) Struct(s interface{}) (err error) {
vd.top = top vd.top = top
vd.isPartial = false vd.isPartial = false
// vd.hasExcludes = false // only need to reset in StructPartial and StructExcept // vd.hasExcludes = false // only need to reset in StructPartial and StructExcept
vd.validateStruct(top, val, val.Type(), vd.ns[0:0], vd.actualNs[0:0], nil) vd.validateStruct(top, val, val.Type(), vd.ns[0:0], vd.actualNs[0:0], nil)
// fmt.Println(cap(vd.ns))
if len(vd.errs) > 0 { if len(vd.errs) > 0 {
err = vd.errs err = vd.errs
vd.errs = nil vd.errs = nil

@ -237,7 +237,7 @@ func StructValidationTestStructSuccess(sl StructLevel) {
st := sl.Current().Interface().(TestStruct) st := sl.Current().Interface().(TestStruct)
if st.String != "good value" { if st.String != "good value" {
sl.ReportError(reflect.ValueOf(st.String), "StringVal", "String", "badvalueteststruct") sl.ReportError(st.String, "StringVal", "String", "badvalueteststruct")
} }
} }
@ -246,7 +246,7 @@ func StructValidationTestStruct(sl StructLevel) {
st := sl.Current().Interface().(TestStruct) st := sl.Current().Interface().(TestStruct)
if st.String != "bad value" { if st.String != "bad value" {
sl.ReportError(reflect.ValueOf(st.String), "StringVal", "String", "badvalueteststruct") sl.ReportError(st.String, "StringVal", "String", "badvalueteststruct")
} }
} }
@ -255,7 +255,7 @@ func StructValidationNoTestStructCustomName(sl StructLevel) {
st := sl.Current().Interface().(TestStruct) st := sl.Current().Interface().(TestStruct)
if st.String != "bad value" { if st.String != "bad value" {
sl.ReportError(reflect.ValueOf(st.String), "String", "", "badvalueteststruct") sl.ReportError(st.String, "String", "", "badvalueteststruct")
} }
} }
@ -264,7 +264,7 @@ func StructValidationTestStructInvalid(sl StructLevel) {
st := sl.Current().Interface().(TestStruct) st := sl.Current().Interface().(TestStruct)
if st.String != "bad value" { if st.String != "bad value" {
sl.ReportError(reflect.ValueOf(nil), "StringVal", "String", "badvalueteststruct") sl.ReportError(nil, "StringVal", "String", "badvalueteststruct")
} }
} }

Loading…
Cancel
Save