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)) }