local.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. package local
  2. import (
  3. "strings"
  4. "sync"
  5. "time"
  6. )
  7. type Cache struct {
  8. namespace string
  9. syncMap *sync.Map
  10. expireRoutineDoneChannelsMutex *sync.Mutex
  11. expireRoutineDoneChannels []chan any
  12. }
  13. func New(namespace string) *Cache {
  14. return &Cache{
  15. namespace: namespace,
  16. syncMap: new(sync.Map),
  17. expireRoutineDoneChannelsMutex: new(sync.Mutex),
  18. expireRoutineDoneChannels: make([]chan any, 0),
  19. }
  20. }
  21. func Destroy(cache *Cache) {
  22. if cache == nil {
  23. return
  24. }
  25. cache.expireRoutineDoneChannelsMutex.Lock()
  26. for _, doneChan := range cache.expireRoutineDoneChannels {
  27. doneChan <- nil
  28. close(doneChan)
  29. doneChan = nil
  30. }
  31. cache.expireRoutineDoneChannels = nil
  32. cache.expireRoutineDoneChannelsMutex.Unlock()
  33. cache.syncMap = nil
  34. }
  35. func (cache *Cache) Set(key string, value string, expireSec int64) error {
  36. cache.syncMap.Store(cache.key2CacheKey(key), value)
  37. if expireSec != 0 {
  38. doneChan := make(chan any)
  39. cache.expireRoutineDoneChannelsMutex.Lock()
  40. if cache.expireRoutineDoneChannels != nil {
  41. cache.expireRoutineDoneChannels = append(cache.expireRoutineDoneChannels, doneChan)
  42. }
  43. cache.expireRoutineDoneChannelsMutex.Unlock()
  44. go func() {
  45. timer := time.NewTimer(time.Second * time.Duration(expireSec))
  46. defer func() {
  47. timer.Stop()
  48. cache.expireRoutineDoneChannelsMutex.Lock()
  49. if cache.expireRoutineDoneChannels != nil {
  50. findIndex := -1
  51. for i, savedDoneChan := range cache.expireRoutineDoneChannels {
  52. if savedDoneChan == doneChan {
  53. findIndex = i
  54. close(savedDoneChan)
  55. savedDoneChan = nil
  56. break
  57. }
  58. }
  59. if findIndex != -1 {
  60. cache.expireRoutineDoneChannels =
  61. append(cache.expireRoutineDoneChannels[:findIndex], cache.expireRoutineDoneChannels[findIndex+1:]...)
  62. }
  63. }
  64. cache.expireRoutineDoneChannelsMutex.Unlock()
  65. }()
  66. for {
  67. select {
  68. case <-timer.C:
  69. cache.syncMap.Delete(cache.key2CacheKey(key))
  70. return
  71. case <-doneChan:
  72. return
  73. }
  74. }
  75. }()
  76. }
  77. return nil
  78. }
  79. func (cache *Cache) Get(key string) (string, error) {
  80. value, loaded := cache.syncMap.Load(cache.key2CacheKey(key))
  81. if !loaded {
  82. return "", nil
  83. }
  84. return value.(string), nil
  85. }
  86. func (cache *Cache) GetMulti(keys []string) (map[string]string, error) {
  87. result := make(map[string]string)
  88. for _, key := range keys {
  89. value, loaded := cache.syncMap.Load(cache.key2CacheKey(key))
  90. if !loaded {
  91. result[key] = ""
  92. }
  93. result[key] = value.(string)
  94. }
  95. return result, nil
  96. }
  97. func (cache *Cache) GetAll() (map[string]string, error) {
  98. result := make(map[string]string)
  99. cache.syncMap.Range(func(key any, value any) bool {
  100. result[cache.cacheKey2Key(key.(string))] = value.(string)
  101. return true
  102. })
  103. return result, nil
  104. }
  105. func (cache *Cache) Delete(key string) error {
  106. cache.syncMap.Delete(cache.key2CacheKey(key))
  107. return nil
  108. }
  109. func (cache *Cache) Clear() error {
  110. cache.syncMap = new(sync.Map)
  111. return nil
  112. }
  113. func (cache *Cache) key2CacheKey(key string) string {
  114. return cache.namespace + "::" + key
  115. }
  116. func (cache *Cache) cacheKey2Key(cacheKey string) string {
  117. return strings.TrimPrefix(cacheKey, cache.namespace+"::")
  118. }