diff --git a/reflect.go b/reflect.go index 39acb320..cbeba959 100644 --- a/reflect.go +++ b/reflect.go @@ -3,6 +3,7 @@ package jsoniter import ( "fmt" "reflect" + "sync" "unsafe" "github.com/modern-go/reflect2" @@ -36,9 +37,36 @@ type checkIsEmpty interface { type ctx struct { *frozenConfig - prefix string - encoders map[reflect2.Type]ValEncoder - decoders map[reflect2.Type]ValDecoder + prefix string + //encoders map[reflect2.Type]ValEncoder + //decoders map[reflect2.Type]ValDecoder + + encoders *sync.Map + decoders *sync.Map +} + +func (c *ctx) getEncoder(t reflect2.Type) ValEncoder { + encoder, found := c.encoders.Load(t) + if found { + return encoder.(ValEncoder) + } + return nil +} + +func (c *ctx) addEncoder(t reflect2.Type, v ValEncoder) { + c.encoders.Store(t, v) +} + +func (c *ctx) getDecoder(t reflect2.Type) ValDecoder { + decoder, found := c.decoders.Load(t) + if found { + return decoder.(ValDecoder) + } + return nil +} + +func (c *ctx) addDecoder(t reflect2.Type, v ValDecoder) { + c.decoders.Store(t, v) } func (b *ctx) caseSensitive() bool { @@ -107,8 +135,8 @@ func (cfg *frozenConfig) DecoderOf(typ reflect2.Type) ValDecoder { ctx := &ctx{ frozenConfig: cfg, prefix: "", - decoders: map[reflect2.Type]ValDecoder{}, - encoders: map[reflect2.Type]ValEncoder{}, + decoders: &sync.Map{}, + encoders: &sync.Map{}, } ptrType := typ.(*reflect2.UnsafePtrType) decoder = decoderOfType(ctx, ptrType.Elem()) @@ -133,14 +161,14 @@ func decoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder { } func createDecoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder { - decoder := ctx.decoders[typ] + decoder := ctx.getDecoder(typ) if decoder != nil { return decoder } placeholder := &placeholderDecoder{} - ctx.decoders[typ] = placeholder decoder = _createDecoderOfType(ctx, typ) placeholder.decoder = decoder + ctx.addDecoder(typ, placeholder) return decoder } @@ -196,8 +224,8 @@ func (cfg *frozenConfig) EncoderOf(typ reflect2.Type) ValEncoder { ctx := &ctx{ frozenConfig: cfg, prefix: "", - decoders: map[reflect2.Type]ValDecoder{}, - encoders: map[reflect2.Type]ValEncoder{}, + decoders: &sync.Map{}, + encoders: &sync.Map{}, } encoder = encoderOfType(ctx, typ) if typ.LikePtr() { @@ -236,14 +264,14 @@ func encoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder { } func createEncoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder { - encoder := ctx.encoders[typ] + encoder := ctx.getEncoder(typ) if encoder != nil { return encoder } placeholder := &placeholderEncoder{} - ctx.encoders[typ] = placeholder encoder = _createEncoderOfType(ctx, typ) placeholder.encoder = encoder + ctx.addEncoder(typ, placeholder) return encoder } func _createEncoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder {