hotime/cache/cache_memory.go
hoteas 3d83c41905 feat(cache): 增加批量操作支持以提升性能
- 在 HoTimeCache 中新增 SessionsGet、SessionsSet 和 SessionsDelete 方法,支持批量获取、设置和删除 Session 缓存
- 优化缓存逻辑,减少数据库写入次数,提升性能
- 更新文档,详细说明批量操作的使用方法和性能对比
- 添加调试日志记录,便于追踪批量操作的执行情况
2026-01-30 17:51:43 +08:00

155 lines
3.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 批量获取缓存
// 返回 Mapkey 为缓存键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: Mapkey 为缓存键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)
}
}