From 3353055b2a1a5ae1b6a8dfde887a524e7088f3a2 Mon Sep 17 00:00:00 2001 From: Tao Wen Date: Wed, 28 Feb 2018 17:11:57 +0800 Subject: [PATCH] use concurrent.Map for 1.8 support --- config.go | 59 ++++++++++++++++++++++++++++++++ config_with_sync_map.go | 64 ---------------------------------- config_without_sync_map.go | 70 -------------------------------------- 3 files changed, 59 insertions(+), 134 deletions(-) delete mode 100644 config_with_sync_map.go delete mode 100644 config_without_sync_map.go diff --git a/config.go b/config.go index 3446170b..b69cdbfc 100644 --- a/config.go +++ b/config.go @@ -6,6 +6,7 @@ import ( "io" "sync" "unsafe" + "github.com/modern-go/concurrent" ) // Config customize how the API should behave. @@ -59,6 +60,64 @@ var ConfigFastest = Config{ ObjectFieldMustBeSimpleString: true, // do not unescape object field }.Froze() + +type frozenConfig struct { + configBeforeFrozen Config + sortMapKeys bool + indentionStep int + objectFieldMustBeSimpleString bool + onlyTaggedField bool + disallowUnknownFields bool + decoderCache *concurrent.Map + encoderCache *concurrent.Map + extensions []Extension + streamPool *sync.Pool + iteratorPool *sync.Pool +} + +func (cfg *frozenConfig) initCache() { + cfg.decoderCache = concurrent.NewMap() + cfg.encoderCache = concurrent.NewMap() +} + +func (cfg *frozenConfig) addDecoderToCache(cacheKey uintptr, decoder ValDecoder) { + cfg.decoderCache.Store(cacheKey, decoder) +} + +func (cfg *frozenConfig) addEncoderToCache(cacheKey uintptr, encoder ValEncoder) { + cfg.encoderCache.Store(cacheKey, encoder) +} + +func (cfg *frozenConfig) getDecoderFromCache(cacheKey uintptr) ValDecoder { + decoder, found := cfg.decoderCache.Load(cacheKey) + if found { + return decoder.(ValDecoder) + } + return nil +} + +func (cfg *frozenConfig) getEncoderFromCache(cacheKey uintptr) ValEncoder { + encoder, found := cfg.encoderCache.Load(cacheKey) + if found { + return encoder.(ValEncoder) + } + return nil +} + +var cfgCache = &sync.Map{} + +func getFrozenConfigFromCache(cfg Config) *frozenConfig { + obj, found := cfgCache.Load(cfg) + if found { + return obj.(*frozenConfig) + } + return nil +} + +func addFrozenConfigToCache(cfg Config, frozenConfig *frozenConfig) { + cfgCache.Store(cfg, frozenConfig) +} + // Froze forge API from config func (cfg Config) Froze() API { api := &frozenConfig{ diff --git a/config_with_sync_map.go b/config_with_sync_map.go deleted file mode 100644 index 7f14812c..00000000 --- a/config_with_sync_map.go +++ /dev/null @@ -1,64 +0,0 @@ -//+build go1.9 - -package jsoniter - -import ( - "sync" -) - -type frozenConfig struct { - configBeforeFrozen Config - sortMapKeys bool - indentionStep int - objectFieldMustBeSimpleString bool - onlyTaggedField bool - disallowUnknownFields bool - decoderCache sync.Map - encoderCache sync.Map - extensions []Extension - streamPool *sync.Pool - iteratorPool *sync.Pool -} - -func (cfg *frozenConfig) initCache() { - cfg.decoderCache = sync.Map{} - cfg.encoderCache = sync.Map{} -} - -func (cfg *frozenConfig) addDecoderToCache(cacheKey uintptr, decoder ValDecoder) { - cfg.decoderCache.Store(cacheKey, decoder) -} - -func (cfg *frozenConfig) addEncoderToCache(cacheKey uintptr, encoder ValEncoder) { - cfg.encoderCache.Store(cacheKey, encoder) -} - -func (cfg *frozenConfig) getDecoderFromCache(cacheKey uintptr) ValDecoder { - decoder, found := cfg.decoderCache.Load(cacheKey) - if found { - return decoder.(ValDecoder) - } - return nil -} - -func (cfg *frozenConfig) getEncoderFromCache(cacheKey uintptr) ValEncoder { - encoder, found := cfg.encoderCache.Load(cacheKey) - if found { - return encoder.(ValEncoder) - } - return nil -} - -var cfgCache = &sync.Map{} - -func getFrozenConfigFromCache(cfg Config) *frozenConfig { - obj, found := cfgCache.Load(cfg) - if found { - return obj.(*frozenConfig) - } - return nil -} - -func addFrozenConfigToCache(cfg Config, frozenConfig *frozenConfig) { - cfgCache.Store(cfg, frozenConfig) -} diff --git a/config_without_sync_map.go b/config_without_sync_map.go deleted file mode 100644 index 5906cd55..00000000 --- a/config_without_sync_map.go +++ /dev/null @@ -1,70 +0,0 @@ -//+build !go1.9 - -package jsoniter - -import ( - "sync" -) - -type frozenConfig struct { - configBeforeFrozen Config - sortMapKeys bool - indentionStep int - objectFieldMustBeSimpleString bool - onlyTaggedField bool - disallowUnknownFields bool - cacheLock *sync.RWMutex - decoderCache map[uintptr]ValDecoder - encoderCache map[uintptr]ValEncoder - extensions []Extension - streamPool *sync.Pool - iteratorPool *sync.Pool -} - -func (cfg *frozenConfig) initCache() { - cfg.cacheLock = &sync.RWMutex{} - cfg.decoderCache = map[uintptr]ValDecoder{} - cfg.encoderCache = map[uintptr]ValEncoder{} -} - -func (cfg *frozenConfig) addDecoderToCache(cacheKey uintptr, decoder ValDecoder) { - cfg.cacheLock.Lock() - cfg.decoderCache[cacheKey] = decoder - cfg.cacheLock.Unlock() -} - -func (cfg *frozenConfig) addEncoderToCache(cacheKey uintptr, encoder ValEncoder) { - cfg.cacheLock.Lock() - cfg.encoderCache[cacheKey] = encoder - cfg.cacheLock.Unlock() -} - -func (cfg *frozenConfig) getDecoderFromCache(cacheKey uintptr) ValDecoder { - cfg.cacheLock.RLock() - decoder, _ := cfg.decoderCache[cacheKey].(ValDecoder) - cfg.cacheLock.RUnlock() - return decoder -} - -func (cfg *frozenConfig) getEncoderFromCache(cacheKey uintptr) ValEncoder { - cfg.cacheLock.RLock() - encoder, _ := cfg.encoderCache[cacheKey].(ValEncoder) - cfg.cacheLock.RUnlock() - return encoder -} - -var cfgCacheLock = &sync.RWMutex{} -var cfgCache = map[Config]*frozenConfig{} - -func getFrozenConfigFromCache(cfg Config) *frozenConfig { - cfgCacheLock.RLock() - frozenConfig := cfgCache[cfg] - cfgCacheLock.RUnlock() - return frozenConfig -} - -func addFrozenConfigToCache(cfg Config, frozenConfig *frozenConfig) { - cfgCacheLock.Lock() - cfgCache[cfg] = frozenConfig - cfgCacheLock.Unlock() -}