hotime/cache/cache_memory.go

116 lines
2.1 KiB
Go
Raw Normal View History

2021-05-24 07:27:41 +08:00
package cache
2017-08-04 08:20:59 +00:00
import (
2022-03-13 01:12:29 +08:00
. "code.hoteas.com/golang/hotime/common"
2018-04-09 17:16:24 +00:00
"strings"
2018-06-13 11:10:13 +00:00
"sync"
"time"
2017-08-04 08:20:59 +00:00
)
// CacheMemory 基于 sync.Map 的缓存实现
2017-08-04 08:20:59 +00:00
type CacheMemory struct {
TimeOut int64
DbSet bool
SessionSet bool
*Error
cache sync.Map // 替代传统的 Map
2017-08-04 08:20:59 +00:00
}
2022-03-13 01:48:54 +08:00
func (that *CacheMemory) GetError() *Error {
2022-03-13 01:48:54 +08:00
return that.Error
}
2022-03-13 01:48:54 +08:00
func (that *CacheMemory) SetError(err *Error) {
that.Error = err
}
func (c *CacheMemory) get(key string) (res *Obj) {
res = &Obj{
Error: *c.Error,
}
value, ok := c.cache.Load(key)
if !ok {
return res // 缓存不存在
2017-08-04 08:20:59 +00:00
}
data := value.(cacheData)
// 检查是否过期
2018-06-13 11:10:13 +00:00
if data.time < time.Now().Unix() {
c.cache.Delete(key) // 删除过期缓存
return res
2017-08-04 08:20:59 +00:00
}
res.Data = data.data
return res
2018-04-04 18:44:00 +00:00
}
func (c *CacheMemory) set(key string, value interface{}, expireAt int64) {
data := cacheData{
data: value,
time: expireAt,
}
c.cache.Store(key, data)
2017-08-04 08:20:59 +00:00
}
func (c *CacheMemory) delete(key string) {
if strings.Contains(key, "*") {
// 通配符删除
prefix := strings.TrimSuffix(key, "*")
c.cache.Range(func(k, v interface{}) bool {
if strings.HasPrefix(k.(string), prefix) {
c.cache.Delete(k)
2018-04-09 17:16:24 +00:00
}
return true
})
2018-06-13 11:10:13 +00:00
} else {
// 精确删除
c.cache.Delete(key)
2018-04-09 17:16:24 +00:00
}
2017-08-04 08:20:59 +00:00
}
func (c *CacheMemory) refreshMap() {
go func() {
now := time.Now().Unix()
c.cache.Range(func(key, value interface{}) bool {
data := value.(cacheData)
if data.time <= now {
c.cache.Delete(key) // 删除过期缓存
}
return true
})
}()
}
func (c *CacheMemory) Cache(key string, data ...interface{}) *Obj {
now := time.Now().Unix()
2017-08-04 08:20:59 +00:00
// 随机触发刷新
if x := RandX(1, 100000); x > 99950 {
c.refreshMap()
2018-06-13 11:10:13 +00:00
}
2018-04-03 17:54:27 +00:00
2018-06-13 11:10:13 +00:00
if len(data) == 0 {
// 读操作
return c.get(key)
2018-06-13 11:10:13 +00:00
}
2018-04-03 17:54:27 +00:00
2018-06-13 11:10:13 +00:00
if len(data) == 1 && data[0] == nil {
// 删除操作
c.delete(key)
return nil
2018-06-13 11:10:13 +00:00
}
2017-08-04 08:20:59 +00:00
// 写操作
expireAt := now + c.TimeOut
2018-06-13 11:10:13 +00:00
if len(data) == 2 {
if customExpire, ok := data[1].(int64); ok {
if customExpire > now {
expireAt = customExpire
} else {
expireAt = now + customExpire
}
2017-08-04 08:20:59 +00:00
}
2018-06-13 11:10:13 +00:00
}
2017-08-04 08:20:59 +00:00
c.set(key, data[0], expireAt)
return nil
2017-08-04 08:20:59 +00:00
}