@@ -14,6 +14,7 @@ import (
1414 "fmt"
1515 "reflect"
1616 "strings"
17+ "sync"
1718 "time"
1819 "unicode"
1920)
@@ -51,8 +52,45 @@ type cachedStruct struct {
5152 fields []* cachedField
5253}
5354
54- var structCache = map [reflect.Type ]* cachedStruct {}
55- var fieldsCache = map [string ][]* cachedTags {}
55+ type structsCacheMap struct {
56+ lock sync.RWMutex
57+ m map [reflect.Type ]* cachedStruct
58+ }
59+
60+ func (s * structsCacheMap ) Get (key reflect.Type ) (* cachedStruct , bool ) {
61+ s .lock .RLock ()
62+ defer s .lock .RUnlock ()
63+ value , ok := s .m [key ]
64+ return value , ok
65+ }
66+
67+ func (s * structsCacheMap ) Set (key reflect.Type , value * cachedStruct ) {
68+ s .lock .Lock ()
69+ defer s .lock .Unlock ()
70+ s .m [key ] = value
71+ }
72+
73+ var structCache = & structsCacheMap {m : map [reflect.Type ]* cachedStruct {}}
74+
75+ type fieldsCacheMap struct {
76+ lock sync.RWMutex
77+ m map [string ][]* cachedTags
78+ }
79+
80+ func (s * fieldsCacheMap ) Get (key string ) ([]* cachedTags , bool ) {
81+ s .lock .RLock ()
82+ defer s .lock .RUnlock ()
83+ value , ok := s .m [key ]
84+ return value , ok
85+ }
86+
87+ func (s * fieldsCacheMap ) Set (key string , value []* cachedTags ) {
88+ s .lock .Lock ()
89+ defer s .lock .Unlock ()
90+ s .m [key ] = value
91+ }
92+
93+ var fieldsCache = & fieldsCacheMap {m : map [string ][]* cachedTags {}}
5694
5795// FieldError contains a single field's validation error along
5896// with other properties that may be needed for error message creation
@@ -205,7 +243,7 @@ func (v *Validate) structRecursive(top interface{}, current interface{}, s inter
205243 var structName string
206244 var numFields int
207245
208- cs , isCached := structCache [ structType ]
246+ cs , isCached := structCache . Get ( structType )
209247
210248 if isCached {
211249 structName = cs .name
@@ -214,7 +252,7 @@ func (v *Validate) structRecursive(top interface{}, current interface{}, s inter
214252 structName = structType .Name ()
215253 numFields = structValue .NumField ()
216254 cs = & cachedStruct {name : structName , children : numFields }
217- structCache [ structType ] = cs
255+ structCache . Set ( structType , cs )
218256 }
219257
220258 validationErrors := & StructErrors {
@@ -374,7 +412,7 @@ func (v *Validate) fieldWithNameAndValue(val interface{}, current interface{}, f
374412 if len (cField .tags ) == 0 {
375413
376414 if isSingleField {
377- cField .tags , isCached = fieldsCache [ tag ]
415+ cField .tags , isCached = fieldsCache . Get ( tag )
378416 }
379417
380418 if ! isCached {
@@ -404,7 +442,7 @@ func (v *Validate) fieldWithNameAndValue(val interface{}, current interface{}, f
404442 }
405443
406444 if isSingleField {
407- fieldsCache [ cField .tag ] = cField .tags
445+ fieldsCache . Set ( cField .tag , cField .tags )
408446 }
409447 }
410448 }
0 commit comments