1 Star 1 Fork 0

go-wena / app

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
cache.go 2.32 KB
一键复制 编辑 原始数据 按行查看 历史
k3x 提交于 2021-06-04 14:09 . init
package app
import (
"encoding/binary"
"encoding/json"
"sync"
"time"
"gitee.com/go-errors/errors"
"gitee.com/go-wena/app/internal/bolt"
)
var Cache = &cacheService{}
type cacheService struct {
db *bolt.DB
err error
once sync.Once
}
var cacheBucket = []byte("cache")
var ErrNotFound = errors.New("not found")
func (c *cacheService) init() {
c.db, c.err = bolt.Open("cache.data", 0644, bolt.DefaultOptions)
}
func (c *cacheService) Get(bucket string, key string, out interface{}) error {
if c.once.Do(c.init); c.err != nil {
return c.err
}
var isExpired bool
err := c.db.View(func(tx *bolt.Tx) error {
bucket := tx.Bucket([]byte(bucket))
if bucket == nil {
return ErrNotFound
}
data := bucket.Get([]byte(key))
if data == nil {
return ErrNotFound
}
if len(data) > 8 {
d := int64(binary.BigEndian.Uint64(data[:8]))
if d > 0 && time.Now().UnixNano() > d {
isExpired = true
return ErrNotFound
}
data = data[8:]
}
return json.Unmarshal(data, out)
})
if err != nil {
return err
}
if isExpired {
_ = c.db.Update(func(tx *bolt.Tx) error {
if bucket := tx.Bucket(cacheBucket); bucket != nil {
return bucket.Delete([]byte(key))
}
return nil
})
}
return nil
}
func (c *cacheService) Set(bucket string, key string, value interface{}, expireIn ...time.Duration) error {
if c.once.Do(c.init); c.err != nil {
return c.err
}
return c.db.Update(func(tx *bolt.Tx) error {
bucket, err := tx.CreateBucketIfNotExists([]byte(bucket))
if err != nil {
return err
}
m, err := json.Marshal(value)
if err != nil {
return err
}
data := make([]byte, len(m)+8)
copy(data[8:], m)
if len(expireIn) > 0 && expireIn[0] > 0 {
binary.BigEndian.PutUint64(data[:8],
uint64(time.Now().Add(expireIn[0]).UnixNano()))
}
return bucket.Put([]byte(key), data)
})
}
func (c *cacheService) NextSequence(bucket string) (seq uint64, err error) {
err = c.db.Update(func(tx *bolt.Tx) error {
bucket, err := tx.CreateBucketIfNotExists([]byte(bucket))
if err != nil {
return err
}
seq, err = bucket.NextSequence()
return err
})
return
}
func (c *cacheService) Sequence(bucket string) (seq uint64, err error) {
err = c.db.View(func(tx *bolt.Tx) error {
if bucket := tx.Bucket([]byte(bucket)); bucket != nil {
seq = bucket.Sequence()
}
return nil
})
return
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/go-wena/app.git
git@gitee.com:go-wena/app.git
go-wena
app
app
v0.0.8

搜索帮助

344bd9b3 5694891 D2dac590 5694891