97 lines
2.1 KiB
Go
97 lines
2.1 KiB
Go
package cache
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type Cache[K comparable, V any] struct {
|
|
mu sync.RWMutex
|
|
data sync.Map // 数据
|
|
cSet func(K, Data[V]) // 设置数据回调
|
|
cGet func(K, Data[V]) // 获取数据回调
|
|
cGetData func(K, Data[V]) // 获取数据内容回调
|
|
cGetTTL func(K, Data[V]) // 获取数据剩余时间回调
|
|
cDel func(K, Data[V]) // 删除数据回调
|
|
cUpData func(K, Data[V]) // 更新数据内容回调
|
|
cUpTTL func(K, Data[V]) // 更新数据剩余时间回调
|
|
fatal func(error) // 致命错误执行的内容
|
|
gc func() // 自动清理过期数据
|
|
persist func() // 持久化数据
|
|
is64Bit bool // 是否为64位系统
|
|
}
|
|
|
|
type Data[V any] struct {
|
|
End time.Time // 过期时间 v.End.IsZero()=true表示永不过期
|
|
Val V // 数据
|
|
}
|
|
|
|
// NewCache 创建一个新的缓存实例
|
|
// K: 键的类型(可比较) V: 值的类型(允许any)
|
|
func NewCache[K comparable, V any]() *Cache[K, V] {
|
|
defFunc := func(k K, d Data[V]) {}
|
|
c := &Cache[K, V]{
|
|
data: sync.Map{},
|
|
cSet: defFunc,
|
|
cGet: defFunc,
|
|
cGetData: defFunc,
|
|
cGetTTL: defFunc,
|
|
cDel: defFunc,
|
|
cUpData: defFunc,
|
|
cUpTTL: defFunc,
|
|
fatal: func(err error) { fmt.Println(err) },
|
|
}
|
|
c.gc = c.collection()
|
|
c.is64Bit = strconv.IntSize == 64
|
|
return c
|
|
}
|
|
|
|
// 自动清理过期数据
|
|
func (c *Cache[K, V]) collection() func() {
|
|
ticker := time.NewTicker(time.Second)
|
|
stopChan := make(chan struct{})
|
|
|
|
go func() {
|
|
for {
|
|
select {
|
|
case <-stopChan:
|
|
return
|
|
case <-ticker.C:
|
|
now := time.Now()
|
|
c.data.Range(func(key, value any) bool {
|
|
if v, ok := value.(*Data[V]); ok {
|
|
if !v.End.IsZero() && v.End.Before(now) {
|
|
c.data.Delete(key)
|
|
}
|
|
}
|
|
return true
|
|
})
|
|
}
|
|
}
|
|
}()
|
|
|
|
return func() {
|
|
ticker.Stop()
|
|
stopChan <- struct{}{}
|
|
}
|
|
}
|
|
|
|
func (c *Cache[K, V]) SetFatalFunc(f func(error)) {
|
|
c.mu.Lock()
|
|
defer c.mu.Unlock()
|
|
c.fatal = f
|
|
}
|
|
|
|
// Destroy 销毁缓存实例
|
|
// 关闭缓存实例
|
|
func (c *Cache[K, V]) Destroy() {
|
|
c.gc()
|
|
if c.persist != nil {
|
|
c.persist()
|
|
}
|
|
c.data.Clear()
|
|
return
|
|
}
|