Files
unitech-golib/lrucache/lrucache.go

109 lines
1.9 KiB
Go
Raw Permalink Normal View History

2020-04-06 19:57:19 +08:00
package lrucache
import (
"errors"
2025-07-22 14:08:24 +08:00
"github.com/MAN00K/unitech_golib/tlog"
2020-04-06 19:57:19 +08:00
"github.com/creachadair/cityhash"
"github.com/hashicorp/golang-lru"
"time"
)
// API
var (
Nil error = errors.New("cache: nil")
ErrExpTime error = errors.New("args error, expTime must be > 0")
dbs map[int]*lru.Cache
)
func Set(key string, value interface{}) error {
return SetEx(key, value, 86400)
}
func SetEx(key string, value interface{}, exp int) error {
return setEx(key, value, exp)
}
func Get(key string) (interface{}, error) {
return get(key)
}
func Del(key string) error {
return del(key)
}
// internal
func init() {
if dbs == nil {
dbs = make(map[int]*lru.Cache, 1024)
for i := 0; i < 1024; i++ {
dbs[i], _ = lru.New(3000)
}
}
go flush()
}
func flush() {
i := 0
for range time.NewTicker(time.Minute).C {
start := time.Now()
shard := i % 1024
db, _ := dbs[shard]
keys := db.Keys()
for _, key := range keys {
if keyS, ok := key.(string); ok {
getByDb(keyS, db)
}
}
i++
tlog.Infof("FlushKey||time=%s||shard=%d||old=%d||new=%d", time.Since(start), shard, len(keys), db.Len())
}
}
type item struct {
d interface{}
t int
}
func setEx(key string, value interface{}, exp int) error {
if exp < 1 {
return ErrExpTime
}
db, _ := dbs[hash(key)]
db.Add(key, &item{d: value, t: int(time.Now().Unix()) + exp})
return nil
}
func get(key string) (interface{}, error) {
db, _ := dbs[hash(key)]
return getByDb(key, db)
}
func getByDb(key string, db *lru.Cache) (interface{}, error) {
if value, ok := db.Get(key); ok {
if item, ok := value.(*item); ok {
if item.t >= int(time.Now().Unix()) {
return item.d, nil
} else {
delByDb(key, db)
}
}
}
return nil, Nil
}
func del(key string) error {
db, _ := dbs[hash(key)]
return delByDb(key, db)
}
func delByDb(key string, db *lru.Cache) error {
db.Remove(key)
return nil
}
func hash(key string) int {
return int(cityhash.Hash32([]byte(key)) % 1024)
}