123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- package local
- import (
- "strings"
- "sync"
- "time"
- )
- type Cache struct {
- namespace string
- syncMap *sync.Map
- expireRoutineDoneChannelsMutex *sync.Mutex
- expireRoutineDoneChannels []chan any
- }
- func New(namespace string) *Cache {
- return &Cache{
- namespace: namespace,
- syncMap: new(sync.Map),
- expireRoutineDoneChannelsMutex: new(sync.Mutex),
- expireRoutineDoneChannels: make([]chan any, 0),
- }
- }
- func Destroy(cache *Cache) {
- if cache == nil {
- return
- }
- cache.expireRoutineDoneChannelsMutex.Lock()
- for _, doneChan := range cache.expireRoutineDoneChannels {
- doneChan <- nil
- close(doneChan)
- doneChan = nil
- }
- cache.expireRoutineDoneChannels = nil
- cache.expireRoutineDoneChannelsMutex.Unlock()
- cache.syncMap = nil
- }
- func (cache *Cache) Set(key string, value string, expireSec int64) error {
- cache.syncMap.Store(cache.key2CacheKey(key), value)
- if expireSec != 0 {
- doneChan := make(chan any)
- cache.expireRoutineDoneChannelsMutex.Lock()
- if cache.expireRoutineDoneChannels != nil {
- cache.expireRoutineDoneChannels = append(cache.expireRoutineDoneChannels, doneChan)
- }
- cache.expireRoutineDoneChannelsMutex.Unlock()
- go func() {
- timer := time.NewTimer(time.Second * time.Duration(expireSec))
- defer func() {
- timer.Stop()
- cache.expireRoutineDoneChannelsMutex.Lock()
- if cache.expireRoutineDoneChannels != nil {
- findIndex := -1
- for i, savedDoneChan := range cache.expireRoutineDoneChannels {
- if savedDoneChan == doneChan {
- findIndex = i
- close(savedDoneChan)
- savedDoneChan = nil
- break
- }
- }
- if findIndex != -1 {
- cache.expireRoutineDoneChannels =
- append(cache.expireRoutineDoneChannels[:findIndex], cache.expireRoutineDoneChannels[findIndex+1:]...)
- }
- }
- cache.expireRoutineDoneChannelsMutex.Unlock()
- }()
- for {
- select {
- case <-timer.C:
- cache.syncMap.Delete(cache.key2CacheKey(key))
- return
- case <-doneChan:
- return
- }
- }
- }()
- }
- return nil
- }
- func (cache *Cache) Get(key string) (string, error) {
- value, loaded := cache.syncMap.Load(cache.key2CacheKey(key))
- if !loaded {
- return "", nil
- }
- return value.(string), nil
- }
- func (cache *Cache) GetMulti(keys []string) (map[string]string, error) {
- result := make(map[string]string)
- for _, key := range keys {
- value, loaded := cache.syncMap.Load(cache.key2CacheKey(key))
- if !loaded {
- result[key] = ""
- }
- result[key] = value.(string)
- }
- return result, nil
- }
- func (cache *Cache) GetAll() (map[string]string, error) {
- result := make(map[string]string)
- cache.syncMap.Range(func(key any, value any) bool {
- result[cache.cacheKey2Key(key.(string))] = value.(string)
- return true
- })
- return result, nil
- }
- func (cache *Cache) Delete(key string) error {
- cache.syncMap.Delete(cache.key2CacheKey(key))
- return nil
- }
- func (cache *Cache) Clear() error {
- cache.syncMap = new(sync.Map)
- return nil
- }
- func (cache *Cache) key2CacheKey(key string) string {
- return cache.namespace + "::" + key
- }
- func (cache *Cache) cacheKey2Key(cacheKey string) string {
- return strings.TrimPrefix(cacheKey, cache.namespace+"::")
- }
|