代码拉取完成,页面将自动刷新
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
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。