@@ -535,52 +535,13 @@ func (d *decoder) decodeString(size uint, offset uint) (string, uint) {
535
535
return string (d .buffer [offset :newOffset ]), newOffset
536
536
}
537
537
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
-
548
538
func (d * decoder ) decodeStruct (
549
539
size uint ,
550
540
offset uint ,
551
541
result reflect.Value ,
552
542
depth int ,
553
543
) (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 )
584
545
585
546
// This fills in embedded structs
586
547
for _ , i := range fields .anonymousFields {
@@ -619,6 +580,44 @@ func (d *decoder) decodeStruct(
619
580
return offset , nil
620
581
}
621
582
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
+
622
621
func (d * decoder ) decodeUint (size uint , offset uint ) (uint64 , uint ) {
623
622
newOffset := offset + size
624
623
bytes := d .buffer [offset :newOffset ]
0 commit comments