package cache import ( . "code.hoteas.com/golang/hotime/common" "strings" "sync" "time" ) // CacheMemory 基于 sync.Map 的缓存实现 type CacheMemory struct { TimeOut int64 DbSet bool SessionSet bool *Error cache sync.Map // 替代传统的 Map } func (that *CacheMemory) GetError() *Error { return that.Error } 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 // 缓存不存在 } data := value.(cacheData) // 检查是否过期 if data.time < time.Now().Unix() { c.cache.Delete(key) // 删除过期缓存 return res } res.Data = data.data return res } func (c *CacheMemory) set(key string, value interface{}, expireAt int64) { data := cacheData{ data: value, time: expireAt, } c.cache.Store(key, data) } 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) } return true }) } else { // 精确删除 c.cache.Delete(key) } } 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() // 随机触发刷新 if x := RandX(1, 100000); x > 99950 { c.refreshMap() } if len(data) == 0 { // 读操作 return c.get(key) } if len(data) == 1 && data[0] == nil { // 删除操作 c.delete(key) return nil } // 写操作 expireAt := now + c.TimeOut if len(data) == 2 { if customExpire, ok := data[1].(int64); ok { if customExpire > now { expireAt = customExpire } else { expireAt = now + customExpire } } } c.set(key, data[0], expireAt) return nil } // CachesGet 批量获取缓存 // 返回 Map,key 为缓存键,value 为缓存值(不存在或过期的 key 不包含在结果中) func (c *CacheMemory) CachesGet(keys []string) Map { result := make(Map, len(keys)) for _, key := range keys { obj := c.get(key) if obj != nil && obj.Data != nil { result[key] = obj.Data } } return result } // CachesSet 批量设置缓存 // data: Map,key 为缓存键,value 为缓存值 // timeout: 可选过期时间(秒),不传则使用默认超时时间 func (c *CacheMemory) CachesSet(data Map, timeout ...int64) { now := time.Now().Unix() expireAt := now + c.TimeOut if len(timeout) > 0 && timeout[0] > 0 { if timeout[0] > now { expireAt = timeout[0] } else { expireAt = now + timeout[0] } } for key, value := range data { c.set(key, value, expireAt) } } // CachesDelete 批量删除缓存 func (c *CacheMemory) CachesDelete(keys []string) { for _, key := range keys { c.delete(key) } }