From 562e77833a8c4d8432d107a8cb30197f641fb7a2 Mon Sep 17 00:00:00 2001 From: joeybloggs Date: Sun, 5 Jul 2015 11:31:09 -0400 Subject: [PATCH 1/3] change to use native sync.Pool for #98 --- validator.go | 51 ++++++++++----------------------------------------- 1 file changed, 10 insertions(+), 41 deletions(-) diff --git a/validator.go b/validator.go index 64f0f85..b2ccb95 100644 --- a/validator.go +++ b/validator.go @@ -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{}, } } @@ -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, @@ -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 @@ -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++ { @@ -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 } From 302c3cffddab1559c7b51199213b5b2b2d3fccbb Mon Sep 17 00:00:00 2001 From: joeybloggs Date: Sun, 5 Jul 2015 11:39:16 -0400 Subject: [PATCH 2/3] to use new sync pool remove go 1.2 support for #98 --- .travis.yml | 1 - benchmarks_test.go | 148 ++++++++++++++++++++++----------------------- 2 files changed, 74 insertions(+), 75 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8ab4aed..34645c6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,6 @@ notificaitons: on_failure: always go: - - 1.2 - 1.3 - 1.4 - tip diff --git a/benchmarks_test.go b/benchmarks_test.go index 2517209..ee836c2 100644 --- a/benchmarks_test.go +++ b/benchmarks_test.go @@ -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) { @@ -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) + } + }) +} From 9d4c0ec3023262c2c5837f8fa97525dd19cd9358 Mon Sep 17 00:00:00 2001 From: joeybloggs Date: Sun, 5 Jul 2015 12:17:07 -0400 Subject: [PATCH 3/3] update travis.ml for overalls, which is giving nothing but problems! --- .travis.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 34645c6..389db22 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,10 +10,11 @@ go: - 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 \ No newline at end of file