|  | 
| 6 | 6 | 	"io" | 
| 7 | 7 | 	"sync" | 
| 8 | 8 | 	"unsafe" | 
|  | 9 | +	"github.com/modern-go/concurrent" | 
| 9 | 10 | ) | 
| 10 | 11 | 
 | 
| 11 | 12 | // Config customize how the API should behave. | 
| @@ -59,6 +60,64 @@ var ConfigFastest = Config{ | 
| 59 | 60 | 	ObjectFieldMustBeSimpleString: true, // do not unescape object field | 
| 60 | 61 | }.Froze() | 
| 61 | 62 | 
 | 
|  | 63 | + | 
|  | 64 | +type frozenConfig struct { | 
|  | 65 | +	configBeforeFrozen            Config | 
|  | 66 | +	sortMapKeys                   bool | 
|  | 67 | +	indentionStep                 int | 
|  | 68 | +	objectFieldMustBeSimpleString bool | 
|  | 69 | +	onlyTaggedField               bool | 
|  | 70 | +	disallowUnknownFields         bool | 
|  | 71 | +	decoderCache                  *concurrent.Map | 
|  | 72 | +	encoderCache                  *concurrent.Map | 
|  | 73 | +	extensions                    []Extension | 
|  | 74 | +	streamPool                    *sync.Pool | 
|  | 75 | +	iteratorPool                  *sync.Pool | 
|  | 76 | +} | 
|  | 77 | + | 
|  | 78 | +func (cfg *frozenConfig) initCache() { | 
|  | 79 | +	cfg.decoderCache = concurrent.NewMap() | 
|  | 80 | +	cfg.encoderCache = concurrent.NewMap() | 
|  | 81 | +} | 
|  | 82 | + | 
|  | 83 | +func (cfg *frozenConfig) addDecoderToCache(cacheKey uintptr, decoder ValDecoder) { | 
|  | 84 | +	cfg.decoderCache.Store(cacheKey, decoder) | 
|  | 85 | +} | 
|  | 86 | + | 
|  | 87 | +func (cfg *frozenConfig) addEncoderToCache(cacheKey uintptr, encoder ValEncoder) { | 
|  | 88 | +	cfg.encoderCache.Store(cacheKey, encoder) | 
|  | 89 | +} | 
|  | 90 | + | 
|  | 91 | +func (cfg *frozenConfig) getDecoderFromCache(cacheKey uintptr) ValDecoder { | 
|  | 92 | +	decoder, found := cfg.decoderCache.Load(cacheKey) | 
|  | 93 | +	if found { | 
|  | 94 | +		return decoder.(ValDecoder) | 
|  | 95 | +	} | 
|  | 96 | +	return nil | 
|  | 97 | +} | 
|  | 98 | + | 
|  | 99 | +func (cfg *frozenConfig) getEncoderFromCache(cacheKey uintptr) ValEncoder { | 
|  | 100 | +	encoder, found := cfg.encoderCache.Load(cacheKey) | 
|  | 101 | +	if found { | 
|  | 102 | +		return encoder.(ValEncoder) | 
|  | 103 | +	} | 
|  | 104 | +	return nil | 
|  | 105 | +} | 
|  | 106 | + | 
|  | 107 | +var cfgCache = &sync.Map{} | 
|  | 108 | + | 
|  | 109 | +func getFrozenConfigFromCache(cfg Config) *frozenConfig { | 
|  | 110 | +	obj, found := cfgCache.Load(cfg) | 
|  | 111 | +	if found { | 
|  | 112 | +		return obj.(*frozenConfig) | 
|  | 113 | +	} | 
|  | 114 | +	return nil | 
|  | 115 | +} | 
|  | 116 | + | 
|  | 117 | +func addFrozenConfigToCache(cfg Config, frozenConfig *frozenConfig) { | 
|  | 118 | +	cfgCache.Store(cfg, frozenConfig) | 
|  | 119 | +} | 
|  | 120 | + | 
| 62 | 121 | // Froze forge API from config | 
| 63 | 122 | func (cfg Config) Froze() API { | 
| 64 | 123 | 	api := &frozenConfig{ | 
|  | 
0 commit comments