Skip to content

Commit aa82be2

Browse files
Use sync.Map approach: no behavoir changes, memorizing the existing function
1 parent 00f06e0 commit aa82be2

File tree

3 files changed

+45
-3
lines changed

3 files changed

+45
-3
lines changed

db.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,13 @@ type DbMap struct {
9393
tablesDynamic map[string]*TableMap // tables that use same go-struct and different db table names
9494
logger GorpLogger
9595
logPrefix string
96+
97+
Cache Cache
98+
}
99+
100+
type Cache interface {
101+
Load(key interface{}) (value interface{}, ok bool)
102+
Store(key, value interface{})
96103
}
97104

98105
func (m *DbMap) dynamicTableAdd(tableName string, tbl *TableMap) {

gorp.go

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,32 @@ func expandNamedQuery(m *DbMap, query string, keyGetter func(key string) reflect
256256
}), args
257257
}
258258

259+
type fieldCacheKey struct {
260+
t reflect.Type
261+
name string
262+
cols string
263+
}
264+
265+
type fieldCacheEntry struct {
266+
mapping [][]int
267+
err error
268+
}
269+
259270
func columnToFieldIndex(m *DbMap, t reflect.Type, name string, cols []string) ([][]int, error) {
271+
var ck fieldCacheKey
272+
var err error
273+
if m.Cache != nil {
274+
ck.t = t
275+
ck.name = name
276+
ck.cols = strings.Join(cols, ",")
277+
278+
rv, ok := m.Cache.Load(ck)
279+
if ok {
280+
entry := rv.(*fieldCacheEntry)
281+
return entry.mapping, entry.err
282+
}
283+
}
284+
260285
colToFieldIndex := make([][]int, len(cols))
261286

262287
// check if type t is a mapped table - if so we'll
@@ -298,13 +323,22 @@ func columnToFieldIndex(m *DbMap, t reflect.Type, name string, cols []string) ([
298323
missingColNames = append(missingColNames, colName)
299324
}
300325
}
326+
301327
if len(missingColNames) > 0 {
302-
return colToFieldIndex, &NoFieldInTypeError{
328+
err = &NoFieldInTypeError{
303329
TypeName: t.Name(),
304330
MissingColNames: missingColNames,
305331
}
306332
}
307-
return colToFieldIndex, nil
333+
334+
if m.Cache != nil {
335+
entry := &fieldCacheEntry{
336+
mapping: colToFieldIndex,
337+
err: err,
338+
}
339+
m.Cache.Store(ck, entry)
340+
}
341+
return colToFieldIndex, err
308342
}
309343

310344
func fieldByName(val reflect.Value, fieldName string) *reflect.Value {

mapping_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package gorp
22

33
import (
44
"reflect"
5+
"sync"
56
"testing"
67
"time"
78
)
@@ -23,7 +24,7 @@ type testCoolUser struct {
2324

2425
func BenchmarkCcolumnToFieldIndex(b *testing.B) {
2526
structType := reflect.TypeOf(testUser{})
26-
dbmap := &DbMap{}
27+
dbmap := &DbMap{Cache: &sync.Map{}}
2728
b.ResetTimer()
2829
for n := 0; n < b.N; n++ {
2930
_, err := columnToFieldIndex(dbmap,

0 commit comments

Comments
 (0)