Skip to content

Commit 30c7eaf

Browse files
committed
Use sync.Map for fields cache
Also, move cache retrieval to its own function.
1 parent f51e9f4 commit 30c7eaf

File tree

1 file changed

+39
-40
lines changed

1 file changed

+39
-40
lines changed

decoder.go

Lines changed: 39 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -535,52 +535,13 @@ func (d *decoder) decodeString(size uint, offset uint) (string, uint) {
535535
return string(d.buffer[offset:newOffset]), newOffset
536536
}
537537

538-
type fieldsType struct {
539-
namedFields map[string]int
540-
anonymousFields []int
541-
}
542-
543-
var (
544-
fieldMap = map[reflect.Type]*fieldsType{}
545-
fieldMapMu sync.RWMutex
546-
)
547-
548538
func (d *decoder) decodeStruct(
549539
size uint,
550540
offset uint,
551541
result reflect.Value,
552542
depth int,
553543
) (uint, error) {
554-
resultType := result.Type()
555-
556-
fieldMapMu.RLock()
557-
fields, ok := fieldMap[resultType]
558-
fieldMapMu.RUnlock()
559-
if !ok {
560-
numFields := resultType.NumField()
561-
namedFields := make(map[string]int, numFields)
562-
var anonymous []int
563-
for i := 0; i < numFields; i++ {
564-
field := resultType.Field(i)
565-
566-
fieldName := field.Name
567-
if tag := field.Tag.Get("maxminddb"); tag != "" {
568-
if tag == "-" {
569-
continue
570-
}
571-
fieldName = tag
572-
}
573-
if field.Anonymous {
574-
anonymous = append(anonymous, i)
575-
continue
576-
}
577-
namedFields[fieldName] = i
578-
}
579-
fieldMapMu.Lock()
580-
fields = &fieldsType{namedFields, anonymous}
581-
fieldMap[resultType] = fields
582-
fieldMapMu.Unlock()
583-
}
544+
fields := cachedFields(result)
584545

585546
// This fills in embedded structs
586547
for _, i := range fields.anonymousFields {
@@ -619,6 +580,44 @@ func (d *decoder) decodeStruct(
619580
return offset, nil
620581
}
621582

583+
type fieldsType struct {
584+
namedFields map[string]int
585+
anonymousFields []int
586+
}
587+
588+
var fieldsMap sync.Map
589+
590+
func cachedFields(result reflect.Value) *fieldsType {
591+
resultType := result.Type()
592+
593+
if fields, ok := fieldsMap.Load(resultType); ok {
594+
return fields.(*fieldsType)
595+
}
596+
numFields := resultType.NumField()
597+
namedFields := make(map[string]int, numFields)
598+
var anonymous []int
599+
for i := 0; i < numFields; i++ {
600+
field := resultType.Field(i)
601+
602+
fieldName := field.Name
603+
if tag := field.Tag.Get("maxminddb"); tag != "" {
604+
if tag == "-" {
605+
continue
606+
}
607+
fieldName = tag
608+
}
609+
if field.Anonymous {
610+
anonymous = append(anonymous, i)
611+
continue
612+
}
613+
namedFields[fieldName] = i
614+
}
615+
fields := &fieldsType{namedFields, anonymous}
616+
fieldsMap.Store(resultType, fields)
617+
618+
return fields
619+
}
620+
622621
func (d *decoder) decodeUint(size uint, offset uint) (uint64, uint) {
623622
newOffset := offset + size
624623
bytes := d.buffer[offset:newOffset]

0 commit comments

Comments
 (0)