2024-05-19 21:24:09 +00:00
|
|
|
package torrent
|
2024-01-28 20:22:49 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
2024-05-19 21:24:09 +00:00
|
|
|
"errors"
|
2024-01-28 20:22:49 +00:00
|
|
|
"fmt"
|
|
|
|
"path/filepath"
|
|
|
|
|
|
|
|
dlog "git.kmsign.ru/royalcat/tstor/src/log"
|
|
|
|
"github.com/anacrolix/torrent/metainfo"
|
|
|
|
"github.com/anacrolix/torrent/types/infohash"
|
|
|
|
"github.com/dgraph-io/badger/v4"
|
|
|
|
)
|
|
|
|
|
2024-05-19 21:24:09 +00:00
|
|
|
var errNotFound = errors.New("not found")
|
|
|
|
|
|
|
|
type infoBytesStore struct {
|
2024-01-28 20:22:49 +00:00
|
|
|
db *badger.DB
|
|
|
|
}
|
|
|
|
|
2024-05-19 21:24:09 +00:00
|
|
|
func newInfoBytesStore(metaDir string) (*infoBytesStore, error) {
|
2024-01-28 20:22:49 +00:00
|
|
|
opts := badger.
|
|
|
|
DefaultOptions(filepath.Join(metaDir, "infobytes")).
|
2024-06-16 21:34:46 +00:00
|
|
|
WithLogger(dlog.BadgerLogger("torrent-client", "infobytes"))
|
2024-01-28 20:22:49 +00:00
|
|
|
db, err := badger.Open(opts)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2024-05-19 21:24:09 +00:00
|
|
|
return &infoBytesStore{db}, nil
|
2024-01-28 20:22:49 +00:00
|
|
|
}
|
|
|
|
|
2024-05-19 21:24:09 +00:00
|
|
|
func (k *infoBytesStore) GetBytes(ih infohash.T) ([]byte, error) {
|
2024-01-28 20:22:49 +00:00
|
|
|
var data []byte
|
|
|
|
err := k.db.View(func(tx *badger.Txn) error {
|
|
|
|
item, err := tx.Get(ih.Bytes())
|
|
|
|
if err != nil {
|
|
|
|
if err == badger.ErrKeyNotFound {
|
2024-05-19 21:24:09 +00:00
|
|
|
return errNotFound
|
2024-01-28 20:22:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return fmt.Errorf("error getting value: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
data, err = item.ValueCopy(data)
|
|
|
|
return err
|
|
|
|
})
|
|
|
|
return data, err
|
|
|
|
}
|
|
|
|
|
2024-05-19 21:24:09 +00:00
|
|
|
func (k *infoBytesStore) Get(ih infohash.T) (*metainfo.MetaInfo, error) {
|
2024-01-28 20:22:49 +00:00
|
|
|
data, err := k.GetBytes(ih)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return metainfo.Load(bytes.NewReader(data))
|
|
|
|
}
|
|
|
|
|
2024-05-19 21:24:09 +00:00
|
|
|
func (me *infoBytesStore) SetBytes(ih infohash.T, data []byte) error {
|
2024-01-28 20:22:49 +00:00
|
|
|
return me.db.Update(func(txn *badger.Txn) error {
|
2024-02-22 22:54:56 +00:00
|
|
|
item, err := txn.Get(ih.Bytes())
|
|
|
|
if err != nil {
|
|
|
|
if err == badger.ErrKeyNotFound {
|
|
|
|
return txn.Set(ih.Bytes(), data)
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return item.Value(func(val []byte) error {
|
|
|
|
if !bytes.Equal(val, data) {
|
|
|
|
return txn.Set(ih.Bytes(), data)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
})
|
2024-01-28 20:22:49 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2024-05-19 21:24:09 +00:00
|
|
|
func (me *infoBytesStore) Set(ih infohash.T, info metainfo.MetaInfo) error {
|
2024-02-22 22:54:56 +00:00
|
|
|
return me.SetBytes(ih, info.InfoBytes)
|
2024-01-28 20:22:49 +00:00
|
|
|
}
|
|
|
|
|
2024-05-19 21:24:09 +00:00
|
|
|
func (k *infoBytesStore) Delete(ih infohash.T) error {
|
2024-01-28 20:22:49 +00:00
|
|
|
return k.db.Update(func(txn *badger.Txn) error {
|
|
|
|
return txn.Delete(ih.Bytes())
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2024-05-19 21:24:09 +00:00
|
|
|
func (me *infoBytesStore) Close() error {
|
2024-01-28 20:22:49 +00:00
|
|
|
return me.db.Close()
|
|
|
|
}
|