Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ notificaitons:
on_failure: always

go:
- 1.2
- 1.3
- 1.4
- 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:
- $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
148 changes: 74 additions & 74 deletions benchmarks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,23 @@ func BenchmarkValidateStructSimple(b *testing.B) {
}
}

// func BenchmarkTemplateParallelSimple(b *testing.B) {
func BenchmarkTemplateParallelSimple(b *testing.B) {

// type Foo struct {
// StringValue string `validate:"min=5,max=10"`
// IntValue int `validate:"min=5,max=10"`
// }
type Foo struct {
StringValue string `validate:"min=5,max=10"`
IntValue int `validate:"min=5,max=10"`
}

// validFoo := &Foo{StringValue: "Foobar", IntValue: 7}
// invalidFoo := &Foo{StringValue: "Fo", IntValue: 3}
validFoo := &Foo{StringValue: "Foobar", IntValue: 7}
invalidFoo := &Foo{StringValue: "Fo", IntValue: 3}

// b.RunParallel(func(pb *testing.PB) {
// for pb.Next() {
// validate.Struct(validFoo)
// validate.Struct(invalidFoo)
// }
// })
// }
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
validate.Struct(validFoo)
validate.Struct(invalidFoo)
}
})
}

func BenchmarkValidateStructLarge(b *testing.B) {

Expand Down Expand Up @@ -101,63 +101,63 @@ func BenchmarkValidateStructLarge(b *testing.B) {
}
}

// func BenchmarkTemplateParallelLarge(b *testing.B) {

// tFail := &TestString{
// Required: "",
// Len: "",
// Min: "",
// Max: "12345678901",
// MinMax: "",
// Lt: "0123456789",
// Lte: "01234567890",
// Gt: "1",
// Gte: "1",
// OmitEmpty: "12345678901",
// Sub: &SubTest{
// Test: "",
// },
// Anonymous: struct {
// A string `validate:"required"`
// }{
// A: "",
// },
// Iface: &Impl{
// F: "12",
// },
// }

// tSuccess := &TestString{
// Required: "Required",
// Len: "length==10",
// Min: "min=1",
// Max: "1234567890",
// MinMax: "12345",
// Lt: "012345678",
// Lte: "0123456789",
// Gt: "01234567890",
// Gte: "0123456789",
// OmitEmpty: "",
// Sub: &SubTest{
// Test: "1",
// },
// SubIgnore: &SubTest{
// Test: "",
// },
// Anonymous: struct {
// A string `validate:"required"`
// }{
// A: "1",
// },
// Iface: &Impl{
// F: "123",
// },
// }

// b.RunParallel(func(pb *testing.PB) {
// for pb.Next() {
// validate.Struct(tSuccess)
// validate.Struct(tFail)
// }
// })
// }
func BenchmarkTemplateParallelLarge(b *testing.B) {

tFail := &TestString{
Required: "",
Len: "",
Min: "",
Max: "12345678901",
MinMax: "",
Lt: "0123456789",
Lte: "01234567890",
Gt: "1",
Gte: "1",
OmitEmpty: "12345678901",
Sub: &SubTest{
Test: "",
},
Anonymous: struct {
A string `validate:"required"`
}{
A: "",
},
Iface: &Impl{
F: "12",
},
}

tSuccess := &TestString{
Required: "Required",
Len: "length==10",
Min: "min=1",
Max: "1234567890",
MinMax: "12345",
Lt: "012345678",
Lte: "0123456789",
Gt: "01234567890",
Gte: "0123456789",
OmitEmpty: "",
Sub: &SubTest{
Test: "1",
},
SubIgnore: &SubTest{
Test: "",
},
Anonymous: struct {
A string `validate:"required"`
}{
A: "1",
},
Iface: &Impl{
F: "123",
},
}

b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
validate.Struct(tSuccess)
validate.Struct(tFail)
}
})
}
51 changes: 10 additions & 41 deletions validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,43 +37,13 @@ const (
mapIndexFieldName = "%s[%v]"
)

var structPool *pool
var structPool *sync.Pool

// Pool holds a channelStructErrors.
type pool struct {
pool chan *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...
// returns new *StructErrors to the pool
func newStructErrors() interface{} {
return &StructErrors{
Errors: map[string]*FieldError{},
StructErrors: map[string]*StructErrors{},
}
}

Expand Down Expand Up @@ -357,7 +327,7 @@ type Validate struct {
// New creates a new Validate instance for use.
func New(tagName string, funcs map[string]Func) *Validate {

structPool = newPool(10)
structPool = &sync.Pool{New: newStructErrors}

return &Validate{
tagName: tagName,
Expand All @@ -377,9 +347,8 @@ func (v *Validate) SetTag(tagName string) {
// nearly all cases. only increase if you have a deeply nested struct structure.
// NOTE: this method is not thread-safe
// 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) {
structPool = newPool(max)
structPool = &sync.Pool{New: newStructErrors}
}

// AddFunction adds a validation Func to a Validate's map of validators denoted by the key
Expand Down Expand Up @@ -440,7 +409,7 @@ func (v *Validate) structRecursive(top interface{}, current interface{}, s inter
cs = &cachedStruct{name: structName, children: numFields}
}

validationErrors := structPool.Borrow()
validationErrors := structPool.Get().(*StructErrors)
validationErrors.Struct = structName

for i := 0; i < numFields; i++ {
Expand Down Expand Up @@ -617,7 +586,7 @@ func (v *Validate) structRecursive(top interface{}, current interface{}, s inter
structCache.Set(structType, cs)

if len(validationErrors.Errors) == 0 && len(validationErrors.StructErrors) == 0 {
structPool.Return(validationErrors)
structPool.Put(validationErrors)
return nil
}

Expand Down