Skip to content

Commit

Permalink
Store fields counts in struct mapping and initialize many slice capac…
Browse files Browse the repository at this point in the history
…ity to improve performances
  • Loading branch information
samonzeweb committed May 4, 2018
1 parent ceeb32c commit b0df693
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 14 deletions.
44 changes: 34 additions & 10 deletions dbreflect/dbreflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ type StructMapping struct {
Name string
structMapping structMappingDetails
opLockSQLName string
fieldCount int
keyCount int
autoCount int
}

// innerStructMapping contains the details of a relation between a struct
Expand Down Expand Up @@ -58,6 +61,7 @@ func NewStructMapping(structInfo reflect.Type) (*StructMapping, error) {
}

sm.Name = sm.structMapping.name
sm.setFieldsCount()

err = sm.setOpLockField()
if err != nil {
Expand Down Expand Up @@ -160,7 +164,7 @@ func (smd *structMappingDetails) newSubStructMapping(structField reflect.StructF
// Optional prefix and relation
var options map[string]string
subStructMapping.prefix, options = smd.tagData(structField.Tag)
if relation,ok := options[optionRelation]; ok {
if relation, ok := options[optionRelation]; ok {
subStructMapping.relation = relation
}

Expand Down Expand Up @@ -194,6 +198,26 @@ func (*structMappingDetails) tagData(tag reflect.StructTag) (string, map[string]
return firstValue, tagMaps
}

// setFieldsCount set all fields count (all, auto, keys)
func (sm *StructMapping) setFieldsCount() {
sm.fieldCount = 0
sm.autoCount = 0
sm.keyCount = 0

f := func(_ string, fieldMapping *fieldMapping, _ *reflect.Value) (stop bool, err error) {
sm.fieldCount++
if fieldMapping.isAuto {
sm.autoCount++
}
if fieldMapping.isKey {
sm.keyCount++
}
return false, nil
}

sm.structMapping.traverseTree("", "", nil, f)
}

// setOpLockField searchs optimistic locking field an update the struct mapping
// with the op lock field data.
// It returns an error if there is more then one op lock field.
Expand Down Expand Up @@ -242,7 +266,7 @@ func isValidNonAutoOpLockFieldType(fieldMapping *fieldMapping) bool {

// GetAllColumnsNames returns the names of all columns.
func (sm *StructMapping) GetAllColumnsNames() []string {
columns := make([]string, 0, 0)
columns := make([]string, 0, sm.fieldCount)

f := func(fullName string, _ *fieldMapping, _ *reflect.Value) (stop bool, err error) {
columns = append(columns, fullName)
Expand All @@ -255,7 +279,7 @@ func (sm *StructMapping) GetAllColumnsNames() []string {

// GetNonAutoColumnsNames returns the names of non auto columns.
func (sm *StructMapping) GetNonAutoColumnsNames() []string {
columns := make([]string, 0, 0)
columns := make([]string, 0, sm.fieldCount-sm.autoCount)

f := func(fullName string, fieldMapping *fieldMapping, _ *reflect.Value) (stop bool, err error) {
if !fieldMapping.isAuto {
Expand All @@ -270,7 +294,7 @@ func (sm *StructMapping) GetNonAutoColumnsNames() []string {

// GetAutoColumnsNames returns the names of auto columns.
func (sm *StructMapping) GetAutoColumnsNames() []string {
columns := make([]string, 0, 0)
columns := make([]string, 0, sm.autoCount)

f := func(fullName string, fieldMapping *fieldMapping, _ *reflect.Value) (stop bool, err error) {
if fieldMapping.isAuto {
Expand All @@ -285,7 +309,7 @@ func (sm *StructMapping) GetAutoColumnsNames() []string {

// GetKeyColumnsNames returns the names of key columns.
func (sm *StructMapping) GetKeyColumnsNames() []string {
columns := make([]string, 0, 0)
columns := make([]string, 0, sm.keyCount)

f := func(fullName string, fieldMapping *fieldMapping, _ *reflect.Value) (stop bool, err error) {
if fieldMapping.isKey {
Expand All @@ -305,7 +329,7 @@ func (sm *StructMapping) GetAllFieldsPointers(s interface{}) []interface{} {
v := reflect.ValueOf(s)
v = reflect.Indirect(v)

pointers := make([]interface{}, 0, 0)
pointers := make([]interface{}, 0, sm.fieldCount)

f := func(fullName string, _ *fieldMapping, value *reflect.Value) (stop bool, err error) {
pointers = append(pointers, value.Addr().Interface())
Expand All @@ -323,7 +347,7 @@ func (sm *StructMapping) GetNonAutoFieldsValues(s interface{}) []interface{} {
v := reflect.ValueOf(s)
v = reflect.Indirect(v)

values := make([]interface{}, 0, 0)
values := make([]interface{}, 0, sm.fieldCount-sm.autoCount)

f := func(fullName string, fieldMapping *fieldMapping, value *reflect.Value) (stop bool, err error) {
if !fieldMapping.isAuto {
Expand All @@ -343,7 +367,7 @@ func (sm *StructMapping) GetKeyFieldsValues(s interface{}) []interface{} {
v := reflect.ValueOf(s)
v = reflect.Indirect(v)

values := make([]interface{}, 0, 0)
values := make([]interface{}, 0, sm.keyCount)

f := func(fullName string, fieldMapping *fieldMapping, value *reflect.Value) (stop bool, err error) {
if fieldMapping.isKey {
Expand Down Expand Up @@ -423,7 +447,7 @@ func (sm *StructMapping) GetAutoFieldsPointers(s interface{}) ([]interface{}, er
v := reflect.ValueOf(s)
v = reflect.Indirect(v)

pointers := make([]interface{}, 0, 0)
pointers := make([]interface{}, 0, sm.autoCount)

f := func(fullName string, fieldMapping *fieldMapping, value *reflect.Value) (stop bool, err error) {
if fieldMapping.isAuto {
Expand Down Expand Up @@ -510,7 +534,7 @@ func (smd *structMappingDetails) traverseTree(relation string, prefix string, st
if relation != "" {
fullName = relation + "." + fullName
}

if startValue != nil {
fieldValue := startValue.FieldByName(fm.name)
stopped, err = f(fullName, &fm, &fieldValue)
Expand Down
2 changes: 2 additions & 0 deletions dbreflect/dbreflect_bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ type Record struct {
Dummy5 string `db:"dummy5"`
}

// go test -bench=GetAllFieldsPointers -run=nore ./dbreflect/ -benchmem -benchtime=10s

// go test -bench=GetAllFieldsPointers -run=none ./dbreflect/ -benchtime=10s -cpuprofile cpu.out
// $GOPATH/bin/pprof -http=localhost:7777 cpu.out

Expand Down
20 changes: 16 additions & 4 deletions dbreflect/dbreflect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ type ComplexStructsWithRelations struct {
// no prefix but a relation
SimpleStruct `db:",rel=firsttable"`
// prefix and relation
Foobar SubStruct `db:"nested_,rel=secondtable"`
Foobar SubStruct `db:"nested_,rel=secondtable"`
}

func TestStructMapping(t *testing.T) {
Expand All @@ -75,11 +75,17 @@ func TestStructMapping(t *testing.T) {
So(structMap.Name, ShouldEndWith, "SimpleStruct")
})

Convey("It store data about all tagged fields ", func() {
Convey("It store data about all tagged fields", func() {
So(len(structMap.GetAllColumnsNames()), ShouldEqual, 2)
So(structMap.GetAllColumnsNames(), ShouldContain, "id")
So(structMap.GetAllColumnsNames(), ShouldContain, "my_text")
})

Convey("It counts fields", func() {
So(structMap.fieldCount, ShouldEqual, 2)
So(structMap.autoCount, ShouldEqual, 1)
So(structMap.keyCount, ShouldEqual, 1)
})
})

Convey("NewStructMapping with a complex struct type with sub-structs", t, func() {
Expand All @@ -96,6 +102,12 @@ func TestStructMapping(t *testing.T) {
So(structMapDetails.subStructMapping[1].prefix, ShouldEqual, "nested_")
So(structMapDetails.subStructMapping[1].structMapping.name, ShouldEndWith, "SubStruct")
})

Convey("It counts fields", func() {
So(structMap.fieldCount, ShouldEqual, 5)
So(structMap.autoCount, ShouldEqual, 1)
So(structMap.keyCount, ShouldEqual, 1)
})
})

Convey("NewStructMapping with nested structs and relations", t, func() {
Expand All @@ -112,7 +124,7 @@ func TestStructMapping(t *testing.T) {
So(structMapDetails.subStructMapping[1].prefix, ShouldEqual, "nested_")
So(structMapDetails.subStructMapping[1].relation, ShouldEndWith, "secondtable")
})
})
})
}

func TestScannableStructs(t *testing.T) {
Expand Down Expand Up @@ -178,7 +190,7 @@ func TestGetAllColumnsNames(t *testing.T) {
So(columns[2], ShouldEqual, "secondtable.nested_foo")
So(columns[3], ShouldEqual, "secondtable.nested_bar")
})
})
})
}

func TestGetNonAutoColumnsNames(t *testing.T) {
Expand Down

0 comments on commit b0df693

Please sign in to comment.