Skip to content

Commit

Permalink
Add faster key for type cache
Browse files Browse the repository at this point in the history
  • Loading branch information
bozaro committed Sep 26, 2017
1 parent 1901982 commit 50f206a
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 19 deletions.
7 changes: 4 additions & 3 deletions bson/bson.go
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,7 @@ type fieldInfo struct {
Inline []int
}

var structMap = make(map[reflect.Type]*structInfo)
var structMap = make(map[typeID]*structInfo)
var structMapMutex sync.RWMutex

type externalPanic string
Expand All @@ -645,7 +645,8 @@ func (e externalPanic) String() string {

func getStructInfo(st reflect.Type) (*structInfo, error) {
structMapMutex.RLock()
sinfo, found := structMap[st]
key := rt2id(st)
sinfo, found := structMap[key]
structMapMutex.RUnlock()
if found {
return sinfo, nil
Expand Down Expand Up @@ -744,7 +745,7 @@ func getStructInfo(st reflect.Type) (*structInfo, error) {
reflect.New(st).Elem(),
}
structMapMutex.Lock()
structMap[st] = sinfo
structMap[key] = sinfo
structMapMutex.Unlock()
return sinfo, nil
}
15 changes: 8 additions & 7 deletions bson/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,31 +73,32 @@ const (
setterAddr
)

var setterStyles map[reflect.Type]int
var setterStyles map[typeID]int
var setterIface reflect.Type
var setterMutex sync.RWMutex

func init() {
var iface Setter
setterIface = reflect.TypeOf(&iface).Elem()
setterStyles = make(map[reflect.Type]int)
setterStyles = make(map[typeID]int)
}

func setterStyle(outt reflect.Type) int {
key := rt2id(outt)
setterMutex.RLock()
style := setterStyles[outt]
style := setterStyles[key]
setterMutex.RUnlock()
if style == setterUnknown {
setterMutex.Lock()
defer setterMutex.Unlock()
if outt.Implements(setterIface) {
setterStyles[outt] = setterType
setterStyles[key] = setterType
} else if reflect.PtrTo(outt).Implements(setterIface) {
setterStyles[outt] = setterAddr
setterStyles[key] = setterAddr
} else {
setterStyles[outt] = setterNone
setterStyles[key] = setterNone
}
style = setterStyles[outt]
style = setterStyles[key]
}
return style
}
Expand Down
19 changes: 10 additions & 9 deletions bson/encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ const (

var itoaCache []string

var getterStyles map[reflect.Type]int
var getterStyles map[typeID]int
var getterIface reflect.Type
var getterMutex sync.RWMutex

Expand All @@ -82,7 +82,7 @@ func init() {
}
var iface Getter
getterIface = reflect.TypeOf(&iface).Elem()
getterStyles = make(map[reflect.Type]int)
getterStyles = make(map[typeID]int)
}

func itoa(i int) string {
Expand All @@ -93,8 +93,9 @@ func itoa(i int) string {
}

func getterStyle(outt reflect.Type) int {
key := rt2id(outt)
getterMutex.RLock()
style := getterStyles[outt]
style := getterStyles[key]
getterMutex.RUnlock()
if style == getterUnknown {
getterMutex.Lock()
Expand All @@ -105,16 +106,16 @@ func getterStyle(outt reflect.Type) int {
vt = vt.Elem()
}
if vt.Implements(getterIface) {
getterStyles[outt] = getterTypeVal
getterStyles[key] = getterTypeVal
} else {
getterStyles[outt] = getterTypePtr
getterStyles[key] = getterTypePtr
}
} else if reflect.PtrTo(outt).Implements(getterIface) {
getterStyles[outt] = getterAddr
getterStyles[key] = getterAddr
} else {
getterStyles[outt] = getterNone
getterStyles[key] = getterNone
}
style = getterStyles[outt]
style = getterStyles[key]
}
return style
}
Expand Down Expand Up @@ -391,7 +392,7 @@ func (e *encoder) addElem(name string, v reflect.Value, minSize bool) {
// Stored as int64
e.addElemName(0x12, name)

e.addInt64(int64(v.Int()/1e6))
e.addInt64(int64(v.Int() / 1e6))
default:
i := v.Int()
if (minSize || v.Type().Kind() != reflect.Int64) && i >= math.MinInt32 && i <= math.MaxInt32 {
Expand Down
13 changes: 13 additions & 0 deletions bson/helper_safe.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// +build !go1.7 safe appengine

package bson

import (
"reflect"
)

type typeID uintptr

func rt2id(rt reflect.Type) typeID {
return typeID(reflect.ValueOf(rt).Pointer())
}
21 changes: 21 additions & 0 deletions bson/helper_unsafe.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// +build !safe
// +build !appengine
// +build go1.7

package bson

import (
"reflect"
"unsafe"
)

type typeID uintptr

type unsafeIntf struct {
typ unsafe.Pointer
word unsafe.Pointer
}

func rt2id(rt reflect.Type) typeID {
return typeID(((*unsafeIntf)(unsafe.Pointer(&rt))).word)
}

0 comments on commit 50f206a

Please sign in to comment.