feature_config.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package jsoniter
  2. import (
  3. "reflect"
  4. "sync/atomic"
  5. "unsafe"
  6. )
  7. type Config struct {
  8. IndentionStep int
  9. decoderCache unsafe.Pointer
  10. encoderCache unsafe.Pointer
  11. }
  12. var DEFAULT_CONFIG = &Config{}
  13. func init() {
  14. initConfig(DEFAULT_CONFIG)
  15. }
  16. func initConfig(cfg *Config) {
  17. atomic.StorePointer(&cfg.decoderCache, unsafe.Pointer(&map[string]Decoder{}))
  18. atomic.StorePointer(&cfg.encoderCache, unsafe.Pointer(&map[string]Encoder{}))
  19. }
  20. func (cfg *Config) addDecoderToCache(cacheKey reflect.Type, decoder Decoder) {
  21. done := false
  22. for !done {
  23. ptr := atomic.LoadPointer(&cfg.decoderCache)
  24. cache := *(*map[reflect.Type]Decoder)(ptr)
  25. copied := map[reflect.Type]Decoder{}
  26. for k, v := range cache {
  27. copied[k] = v
  28. }
  29. copied[cacheKey] = decoder
  30. done = atomic.CompareAndSwapPointer(&cfg.decoderCache, ptr, unsafe.Pointer(&copied))
  31. }
  32. }
  33. func (cfg *Config) addEncoderToCache(cacheKey reflect.Type, encoder Encoder) {
  34. done := false
  35. for !done {
  36. ptr := atomic.LoadPointer(&cfg.encoderCache)
  37. cache := *(*map[reflect.Type]Encoder)(ptr)
  38. copied := map[reflect.Type]Encoder{}
  39. for k, v := range cache {
  40. copied[k] = v
  41. }
  42. copied[cacheKey] = encoder
  43. done = atomic.CompareAndSwapPointer(&cfg.encoderCache, ptr, unsafe.Pointer(&copied))
  44. }
  45. }
  46. func (cfg *Config) getDecoderFromCache(cacheKey reflect.Type) Decoder {
  47. ptr := atomic.LoadPointer(&cfg.decoderCache)
  48. cache := *(*map[reflect.Type]Decoder)(ptr)
  49. return cache[cacheKey]
  50. }
  51. func (cfg *Config) getEncoderFromCache(cacheKey reflect.Type) Encoder {
  52. ptr := atomic.LoadPointer(&cfg.encoderCache)
  53. cache := *(*map[reflect.Type]Encoder)(ptr)
  54. return cache[cacheKey]
  55. }
  56. // CleanDecoders cleans decoders registered or cached
  57. func (cfg *Config) CleanDecoders() {
  58. typeDecoders = map[string]Decoder{}
  59. fieldDecoders = map[string]Decoder{}
  60. atomic.StorePointer(&cfg.decoderCache, unsafe.Pointer(&map[string]Decoder{}))
  61. }
  62. // CleanEncoders cleans encoders registered or cached
  63. func (cfg *Config) CleanEncoders() {
  64. typeEncoders = map[string]Encoder{}
  65. fieldEncoders = map[string]Encoder{}
  66. atomic.StorePointer(&cfg.encoderCache, unsafe.Pointer(&map[string]Encoder{}))
  67. }