@@ -18,6 +18,7 @@ package schema
1818
1919import (
2020 "sync"
21+ "sync/atomic"
2122)
2223
2324// Schema is a list of named types.
@@ -28,7 +29,7 @@ type Schema struct {
2829 Types []TypeDef `yaml:"types,omitempty"`
2930
3031 once sync.Once
31- m map [string ]TypeDef
32+ m atomic. Pointer [ map [string ]TypeDef ]
3233
3334 lock sync.Mutex
3435 // Cached results of resolving type references to atoms. Only stores
@@ -144,26 +145,28 @@ type Map struct {
144145 ElementRelationship ElementRelationship `yaml:"elementRelationship,omitempty"`
145146
146147 once sync.Once
147- m map [string ]StructField
148+ m atomic. Pointer [ map [string ]StructField ]
148149}
149150
150151// FindField is a convenience function that returns the referenced StructField,
151152// if it exists, or (nil, false) if it doesn't.
152153func (m * Map ) FindField (name string ) (StructField , bool ) {
153154 m .once .Do (func () {
154- m . m = make (map [string ]StructField , len (m .Fields ))
155+ mm : = make (map [string ]StructField , len (m .Fields ))
155156 for _ , field := range m .Fields {
156- m . m [field .Name ] = field
157+ mm [field .Name ] = field
157158 }
159+ m .m .Store (& mm )
158160 })
159- sf , ok := m .m [name ]
161+ sf , ok := ( * m .m . Load ()) [name ]
160162 return sf , ok
161163}
162164
163- // CopyInto this instance of Map into the other
164- // If other is nil this method does nothing.
165- // If other is already initialized, overwrites it with this instance
166- // Warning: Not thread safe
165+ // CopyInto clones this instance of Map into dst
166+ //
167+ // If dst is nil this method does nothing.
168+ // If dst is already initialized, overwrites it with this instance.
169+ // Warning: Not thread safe. Only use dst after this function returns.
167170func (m * Map ) CopyInto (dst * Map ) {
168171 if dst == nil {
169172 return
@@ -175,12 +178,13 @@ func (m *Map) CopyInto(dst *Map) {
175178 dst .Unions = m .Unions
176179 dst .ElementRelationship = m .ElementRelationship
177180
178- if m .m != nil {
181+ mm := m .m .Load ()
182+ if mm != nil {
179183 // If cache is non-nil then the once token had been consumed.
180184 // Must reset token and use it again to ensure same semantics.
181185 dst .once = sync.Once {}
182186 dst .once .Do (func () {
183- dst .m = m . m
187+ dst .m . Store ( mm )
184188 })
185189 }
186190}
@@ -274,12 +278,13 @@ type List struct {
274278// if it exists, or (nil, false) if it doesn't.
275279func (s * Schema ) FindNamedType (name string ) (TypeDef , bool ) {
276280 s .once .Do (func () {
277- s . m = make (map [string ]TypeDef , len (s .Types ))
281+ sm : = make (map [string ]TypeDef , len (s .Types ))
278282 for _ , t := range s .Types {
279- s . m [t .Name ] = t
283+ sm [t .Name ] = t
280284 }
285+ s .m .Store (& sm )
281286 })
282- t , ok := s .m [name ]
287+ t , ok := ( * s .m . Load ()) [name ]
283288 return t , ok
284289}
285290
@@ -352,10 +357,11 @@ func (s *Schema) Resolve(tr TypeRef) (Atom, bool) {
352357 return result , true
353358}
354359
355- // Clones this instance of Schema into the other
356- // If other is nil this method does nothing.
357- // If other is already initialized, overwrites it with this instance
358- // Warning: Not thread safe
360+ // CopyInto clones this instance of Schema into dst
361+ //
362+ // If dst is nil this method does nothing.
363+ // If dst is already initialized, overwrites it with this instance.
364+ // Warning: Not thread safe. Only use dst after this function returns.
359365func (s * Schema ) CopyInto (dst * Schema ) {
360366 if dst == nil {
361367 return
@@ -364,12 +370,13 @@ func (s *Schema) CopyInto(dst *Schema) {
364370 // Schema type is considered immutable so sharing references
365371 dst .Types = s .Types
366372
367- if s .m != nil {
373+ sm := s .m .Load ()
374+ if sm != nil {
368375 // If cache is non-nil then the once token had been consumed.
369376 // Must reset token and use it again to ensure same semantics.
370377 dst .once = sync.Once {}
371378 dst .once .Do (func () {
372- dst .m = s . m
379+ dst .m . Store ( sm )
373380 })
374381 }
375382}
0 commit comments