feature_config.go 2.1 KB

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