Merge pull request #104 from bluesuncorp/v5

merge latest changes from v5
pull/115/head
Dean Karn 10 years ago
commit 6ae2952f55
  1. 14
      .travis.yml
  2. 148
      benchmarks_test.go
  3. 51
      validator.go

@ -7,14 +7,14 @@ notificaitons:
on_failure: always on_failure: always
go: go:
- 1.2
- 1.3 - 1.3
- 1.4 - 1.4
- tip - tip
before_install:
- go get github.com/axw/gocov/gocov
- go get github.com/mattn/goveralls
- if ! go get code.google.com/p/go.tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi
script: script:
- $HOME/gopath/bin/goveralls -service=travis-ci - go get golang.org/x/tools/cmd/cover
- go get github.com/mattn/goveralls
- go test -v -covermode=count -coverprofile=cover.out
after_success:
- goveralls -coverprofile=cover.out -service=travis-ci -repotoken I6M8FiXZzErImgwMotJ7fwFlHOX8Hqdq1

@ -24,23 +24,23 @@ func BenchmarkValidateStructSimple(b *testing.B) {
} }
} }
// func BenchmarkTemplateParallelSimple(b *testing.B) { func BenchmarkTemplateParallelSimple(b *testing.B) {
// type Foo struct { type Foo struct {
// StringValue string `validate:"min=5,max=10"` StringValue string `validate:"min=5,max=10"`
// IntValue int `validate:"min=5,max=10"` IntValue int `validate:"min=5,max=10"`
// } }
// validFoo := &Foo{StringValue: "Foobar", IntValue: 7} validFoo := &Foo{StringValue: "Foobar", IntValue: 7}
// invalidFoo := &Foo{StringValue: "Fo", IntValue: 3} invalidFoo := &Foo{StringValue: "Fo", IntValue: 3}
// b.RunParallel(func(pb *testing.PB) { b.RunParallel(func(pb *testing.PB) {
// for pb.Next() { for pb.Next() {
// validate.Struct(validFoo) validate.Struct(validFoo)
// validate.Struct(invalidFoo) validate.Struct(invalidFoo)
// } }
// }) })
// } }
func BenchmarkValidateStructLarge(b *testing.B) { func BenchmarkValidateStructLarge(b *testing.B) {
@ -101,63 +101,63 @@ func BenchmarkValidateStructLarge(b *testing.B) {
} }
} }
// func BenchmarkTemplateParallelLarge(b *testing.B) { func BenchmarkTemplateParallelLarge(b *testing.B) {
// tFail := &TestString{ tFail := &TestString{
// Required: "", Required: "",
// Len: "", Len: "",
// Min: "", Min: "",
// Max: "12345678901", Max: "12345678901",
// MinMax: "", MinMax: "",
// Lt: "0123456789", Lt: "0123456789",
// Lte: "01234567890", Lte: "01234567890",
// Gt: "1", Gt: "1",
// Gte: "1", Gte: "1",
// OmitEmpty: "12345678901", OmitEmpty: "12345678901",
// Sub: &SubTest{ Sub: &SubTest{
// Test: "", Test: "",
// }, },
// Anonymous: struct { Anonymous: struct {
// A string `validate:"required"` A string `validate:"required"`
// }{ }{
// A: "", A: "",
// }, },
// Iface: &Impl{ Iface: &Impl{
// F: "12", F: "12",
// }, },
// } }
// tSuccess := &TestString{ tSuccess := &TestString{
// Required: "Required", Required: "Required",
// Len: "length==10", Len: "length==10",
// Min: "min=1", Min: "min=1",
// Max: "1234567890", Max: "1234567890",
// MinMax: "12345", MinMax: "12345",
// Lt: "012345678", Lt: "012345678",
// Lte: "0123456789", Lte: "0123456789",
// Gt: "01234567890", Gt: "01234567890",
// Gte: "0123456789", Gte: "0123456789",
// OmitEmpty: "", OmitEmpty: "",
// Sub: &SubTest{ Sub: &SubTest{
// Test: "1", Test: "1",
// }, },
// SubIgnore: &SubTest{ SubIgnore: &SubTest{
// Test: "", Test: "",
// }, },
// Anonymous: struct { Anonymous: struct {
// A string `validate:"required"` A string `validate:"required"`
// }{ }{
// A: "1", A: "1",
// }, },
// Iface: &Impl{ Iface: &Impl{
// F: "123", F: "123",
// }, },
// } }
// b.RunParallel(func(pb *testing.PB) { b.RunParallel(func(pb *testing.PB) {
// for pb.Next() { for pb.Next() {
// validate.Struct(tSuccess) validate.Struct(tSuccess)
// validate.Struct(tFail) validate.Struct(tFail)
// } }
// }) })
// } }

@ -37,43 +37,13 @@ const (
mapIndexFieldName = "%s[%v]" mapIndexFieldName = "%s[%v]"
) )
var structPool *pool var structPool *sync.Pool
// Pool holds a channelStructErrors. // returns new *StructErrors to the pool
type pool struct { func newStructErrors() interface{} {
pool chan *StructErrors return &StructErrors{
} Errors: map[string]*FieldError{},
StructErrors: map[string]*StructErrors{},
// NewPool creates a new pool of Clients.
func newPool(max int) *pool {
return &pool{
pool: make(chan *StructErrors, max),
}
}
// Borrow a StructErrors from the pool.
func (p *pool) Borrow() *StructErrors {
var c *StructErrors
select {
case c = <-p.pool:
default:
c = &StructErrors{
Errors: map[string]*FieldError{},
StructErrors: map[string]*StructErrors{},
}
}
return c
}
// Return returns a StructErrors to the pool.
func (p *pool) Return(c *StructErrors) {
select {
case p.pool <- c:
default:
// let it go, let it go...
} }
} }
@ -357,7 +327,7 @@ type Validate struct {
// New creates a new Validate instance for use. // New creates a new Validate instance for use.
func New(tagName string, funcs map[string]Func) *Validate { func New(tagName string, funcs map[string]Func) *Validate {
structPool = newPool(10) structPool = &sync.Pool{New: newStructErrors}
return &Validate{ return &Validate{
tagName: tagName, tagName: tagName,
@ -377,9 +347,8 @@ func (v *Validate) SetTag(tagName string) {
// nearly all cases. only increase if you have a deeply nested struct structure. // nearly all cases. only increase if you have a deeply nested struct structure.
// NOTE: this method is not thread-safe // NOTE: this method is not thread-safe
// NOTE: this is only here to keep compatibility with v5, in v6 the method will be removed // NOTE: this is only here to keep compatibility with v5, in v6 the method will be removed
// and the max pool size will be passed into the New function
func (v *Validate) SetMaxStructPoolSize(max int) { func (v *Validate) SetMaxStructPoolSize(max int) {
structPool = newPool(max) structPool = &sync.Pool{New: newStructErrors}
} }
// AddFunction adds a validation Func to a Validate's map of validators denoted by the key // AddFunction adds a validation Func to a Validate's map of validators denoted by the key
@ -440,7 +409,7 @@ func (v *Validate) structRecursive(top interface{}, current interface{}, s inter
cs = &cachedStruct{name: structName, children: numFields} cs = &cachedStruct{name: structName, children: numFields}
} }
validationErrors := structPool.Borrow() validationErrors := structPool.Get().(*StructErrors)
validationErrors.Struct = structName validationErrors.Struct = structName
for i := 0; i < numFields; i++ { for i := 0; i < numFields; i++ {
@ -617,7 +586,7 @@ func (v *Validate) structRecursive(top interface{}, current interface{}, s inter
structCache.Set(structType, cs) structCache.Set(structType, cs)
if len(validationErrors.Errors) == 0 && len(validationErrors.StructErrors) == 0 { if len(validationErrors.Errors) == 0 && len(validationErrors.StructErrors) == 0 {
structPool.Return(validationErrors) structPool.Put(validationErrors)
return nil return nil
} }

Loading…
Cancel
Save