1 Star 1 Fork 5

夏季的风/数据和文件存储组件

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
CacheRepository.go 5.70 KB
一键复制 编辑 原始数据 按行查看 历史
lingbinbin 提交于 2023-08-03 20:00 +08:00 . *修改应用程序缓存
package appCache
import (
"errors"
"gitee.com/ling-bin/go-utils/timingwheel"
"sync"
"sync/atomic"
"time"
)
var(
lock sync.Mutex
_CacheId int64
cachePoolMap = sync.Map{}
timingWhee = timingwheel.NewTimingWheel(time.Second, 60) //初始化秒级多层时间轮
notfound = errors.New(" key not found!")
)
//初始化
func init() {
timingWhee.Start()
}
//GetCacheRepository 获取缓存仺储
func GetCacheRepository(entityName string) ICacheRepository {
if val, ok := cachePoolMap.Load(entityName); ok {
return val.(ICacheRepository)
}
lock.Lock()
defer lock.Unlock()
if val, ok := cachePoolMap.Load(entityName); ok {
return val.(ICacheRepository)
}
repository := &CacheRepository{
entityName: entityName,
cacheMap: sync.Map{},
}
cachePoolMap.Store(entityName, repository)
return repository
}
//CacheRepository 缓存仓储
type CacheRepository struct {
entityName string
cacheMap sync.Map
}
//GetOrAddDuration 获取没有就添加
func (c *CacheRepository) GetOrAddDuration(key string,foundCall func(key string) interface{}, duration time.Duration) (entity interface{},err error) {
result, ok := c.cacheMap.Load(key)
if !ok {
result = foundCall(key)
c.SetDuration(key, result, duration)
return result, nil
}
cacheItem := result.(*cacheItem)
ctime := time.Now().UTC()
if ctime.Sub(cacheItem.expireTime).Seconds() > 0 {
return nil, notfound
}
if cacheItem.duration != 0 {
cacheItem.expireTime = time.Now().UTC().Add(cacheItem.duration)
}
cacheItem.Count++
return cacheItem.value, nil
}
//GetOrAdd 获取没有就添加
func (c *CacheRepository) GetOrAdd(key string,foundCall func(key string) interface{},ttl int, expireFrontCall func(interface{},int64),frontNotice int) (entity interface{},err error) {
result, ok := c.cacheMap.Load(key)
if !ok {
result = foundCall(key)
c.Set(key, result, ttl, expireFrontCall, frontNotice)
return result, nil
}
cacheItem := result.(*cacheItem)
ctime := time.Now().UTC()
if ctime.Sub(cacheItem.expireTime).Seconds() > 0 {
return nil, notfound
}
if cacheItem.duration != 0 {
cacheItem.expireTime = time.Now().UTC().Add(cacheItem.duration)
}
cacheItem.Count++
return cacheItem.value, nil
}
//Get 获取单个
//key 数据唯一key
func (c *CacheRepository) Get(key string)(entity interface{},err error) {
result, ok := c.cacheMap.Load(key)
if !ok {
return nil, notfound
}
cacheItem := result.(*cacheItem)
ctime := time.Now().UTC()
if ctime.Sub(cacheItem.expireTime).Seconds() > 0 {
return nil, notfound
}
if cacheItem.duration != 0 {
cacheItem.expireTime = time.Now().UTC().Add(cacheItem.duration)
}
cacheItem.Count++
return cacheItem.value, nil
}
//Remove 删除单个
// key key值
func (c *CacheRepository) Remove(key string) {
c.cacheMap.Delete(key)
}
// SetDuration 插入单个
// key 数据唯一key
// entity 结构体
// duration 滑动到期时间,访问延期
func (c *CacheRepository) SetDuration(key string, entity interface{}, duration time.Duration) {
id := atomic.AddInt64(&_CacheId, 1)
cacheItem := &cacheItem{
key: key,
value: entity,
duration: duration,
expireTime: time.Now().UTC().Add(duration),
expireFrontCall: nil,
frontNotice: 0,
Count: 0,
Id: id,
}
c.cacheMap.Store(key, cacheItem)
expTime := cacheItem.expireTime
timingWhee.AfterTimeFunc(expTime, func() {
c.clearSlide(key, id, expTime)
})
}
//清理滑动
func (c *CacheRepository) clearSlide(key string,id int64, odExpTime time.Time) {
result, ok := c.cacheMap.Load(key)
if !ok {
return
}
cacheItem := result.(*cacheItem)
if cacheItem.Id != id {
return
}
//有访问延期情况
if cacheItem.expireTime.Sub(odExpTime).Seconds() > 0 {
expTime := cacheItem.expireTime
timingWhee.AfterTimeFunc(cacheItem.expireTime, func() {
c.clearSlide(key, id, expTime)
})
//fmt.Println("滑动")
return
}
c.cacheMap.Delete(key)
//fmt.Println("清理")
}
//frontCall 提前通知
func (c *CacheRepository) frontCall(key string,id int64) {
defer func() {
if r := recover(); r != nil {
return
}
}()
result, ok := c.cacheMap.Load(key)
if !ok {
return
}
cacheItem := result.(*cacheItem)
if cacheItem.Id != id {
return
}
cacheItem.expireFrontCall(cacheItem.value, id)
//fmt.Println("通知")
}
//clear 清理
func (c *CacheRepository) clear(key string,id int64) {
result, ok := c.cacheMap.Load(key)
if !ok {
return
}
cacheItem := result.(*cacheItem)
if cacheItem.Id != id {
return
}
c.cacheMap.Delete(key)
//fmt.Println("清理")
}
// Set 插入单个
// key 数据唯一key
// entity 结构体
// ttl 单位秒 ,0为永不到期
// expireFrontCall 到期前回调
// frontNotice 提前回调时间 秒
func (c *CacheRepository) Set(key string, entity interface{}, ttl int, expireFrontCall func(interface{},int64),frontNotice int) {
ttlSecond := time.Second * time.Duration(ttl)
id := atomic.AddInt64(&_CacheId, 1)
cacheItem := &cacheItem{
key: key,
value: entity,
duration: 0,
expireTime: time.Now().UTC().Add(ttlSecond),
expireFrontCall: expireFrontCall,
frontNotice: frontNotice,
Count: 0,
Id: id,
}
c.cacheMap.Store(key, cacheItem)
timingWhee.AfterTimeFunc(cacheItem.expireTime, func() {
c.clear(key, id)
})
if cacheItem.expireFrontCall != nil {
expire := cacheItem.expireTime.Add(-(time.Second * time.Duration(frontNotice)))
timingWhee.AfterTimeFunc(expire, func() {
c.frontCall(key, id)
})
}
}
// cache 缓存
type cacheItem struct {
key string
value interface{}
duration time.Duration
expireTime time.Time //UTC时间
expireFrontCall func(interface{}, int64)
frontNotice int
Count int64
Id int64
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/ling-bin/repository.git
git@gitee.com:ling-bin/repository.git
ling-bin
repository
数据和文件存储组件
v1.6.22

搜索帮助