@@ -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-
548538func (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+
622621func (d * decoder ) decodeUint (size uint , offset uint ) (uint64 , uint ) {
623622 newOffset := offset + size
624623 bytes := d .buffer [offset :newOffset ]
0 commit comments