uniugm/admin/lib/cache/cache_local.go

102 lines
1.9 KiB
Go
Raw Permalink Normal View History

2025-05-09 18:28:15 +08:00
package cache
import (
"crypto/sha256"
"encoding/binary"
"sync"
"time"
)
type cacheData struct {
data any
expireAt time.Time
}
type localCache struct {
locker *sync.RWMutex
repo map[string]*cacheData
}
func newLocalCache() *localCache {
c := &localCache{
locker: new(sync.RWMutex),
repo: make(map[string]*cacheData),
}
return c
}
func (c *localCache) startBgCheckWorker() {
ticker := time.NewTicker(time.Second * 10)
for {
select {
case <-ticker.C:
timeNow := time.Now()
c.locker.Lock()
for k, v := range c.repo {
if v.expireAt.Before(timeNow) {
delete(c.repo, k)
}
}
c.locker.Unlock()
}
}
}
func (c *localCache) get(key string) (any, bool) {
c.locker.RLocker()
defer c.locker.RUnlock()
v, find := c.repo[key]
if find {
if v.expireAt.Before(time.Now()) {
return nil, false
}
return v.data, true
}
return nil, false
}
func (c *localCache) set(key string, value any, dura time.Duration) {
c.locker.Lock()
defer c.locker.Unlock()
c.repo[key] = &cacheData{
data: value,
expireAt: time.Now().Add(dura),
}
}
type LocalCache struct {
repoList [10]*localCache
}
func NewLocalCache() *LocalCache {
c := &LocalCache{}
for i := 0; i < len(c.repoList); i++ {
c.repoList[i] = newLocalCache()
}
return c
}
func (c *LocalCache) Get(key string) (any, bool) {
return c.getHashRepo(key).get(key)
}
func (c *LocalCache) Set(key string, value any, dura time.Duration) {
c.getHashRepo(key).set(key, value, dura)
}
func (c *LocalCache) getHashRepo(key string) *localCache {
return c.repoList[fastHashMod(key, len(c.repoList))]
}
func fastHashMod(key string, mod int) int {
// 使用前64位哈希值
hasher := sha256.New()
hasher.Write([]byte(key))
hashBytes := hasher.Sum(nil)
// 取前8字节转换为uint64
hashUint64 := binary.BigEndian.Uint64(hashBytes[:8])
return int(hashUint64 % uint64(mod))
}