mirror of
https://github.com/SagerNet/sing-box.git
synced 2024-11-27 11:01:28 +00:00
66 lines
1.3 KiB
Go
66 lines
1.3 KiB
Go
package cachefile
|
|
|
|
import (
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/sagernet/sing-box/adapter"
|
|
|
|
"go.etcd.io/bbolt"
|
|
)
|
|
|
|
var bucketSelected = []byte("selected")
|
|
|
|
var _ adapter.ClashCacheFile = (*CacheFile)(nil)
|
|
|
|
type CacheFile struct {
|
|
DB *bbolt.DB
|
|
}
|
|
|
|
func Open(path string) (*CacheFile, error) {
|
|
const fileMode = 0o666
|
|
options := bbolt.Options{Timeout: time.Second}
|
|
db, err := bbolt.Open(path, fileMode, &options)
|
|
switch err {
|
|
case bbolt.ErrInvalid, bbolt.ErrChecksum, bbolt.ErrVersionMismatch:
|
|
if err = os.Remove(path); err != nil {
|
|
break
|
|
}
|
|
db, err = bbolt.Open(path, 0o666, &options)
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &CacheFile{db}, nil
|
|
}
|
|
|
|
func (c *CacheFile) LoadSelected(group string) string {
|
|
var selected string
|
|
c.DB.View(func(t *bbolt.Tx) error {
|
|
bucket := t.Bucket(bucketSelected)
|
|
if bucket == nil {
|
|
return nil
|
|
}
|
|
selectedBytes := bucket.Get([]byte(group))
|
|
if len(selectedBytes) > 0 {
|
|
selected = string(selectedBytes)
|
|
}
|
|
return nil
|
|
})
|
|
return selected
|
|
}
|
|
|
|
func (c *CacheFile) StoreSelected(group, selected string) error {
|
|
return c.DB.Batch(func(t *bbolt.Tx) error {
|
|
bucket, err := t.CreateBucketIfNotExists(bucketSelected)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return bucket.Put([]byte(group), []byte(selected))
|
|
})
|
|
}
|
|
|
|
func (c *CacheFile) Close() error {
|
|
return c.DB.Close()
|
|
}
|