2021-07-14 12:35:52 +08:00
|
|
|
//go:build !noboltdb && !wasm
|
2021-10-28 16:53:04 +08:00
|
|
|
// +build !noboltdb,!wasm
|
2021-05-25 16:48:59 +08:00
|
|
|
|
2016-08-31 15:48:50 +08:00
|
|
|
package storage
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/binary"
|
|
|
|
"path/filepath"
|
2018-01-09 20:11:34 +08:00
|
|
|
"time"
|
2016-08-31 15:48:50 +08:00
|
|
|
|
2018-04-12 09:34:24 +08:00
|
|
|
"github.com/anacrolix/missinggo/expect"
|
2020-03-24 09:54:57 +08:00
|
|
|
"go.etcd.io/bbolt"
|
2019-08-21 18:58:40 +08:00
|
|
|
|
|
|
|
"github.com/anacrolix/torrent/metainfo"
|
2016-08-31 15:48:50 +08:00
|
|
|
)
|
|
|
|
|
2016-08-31 19:00:44 +08:00
|
|
|
const (
|
2021-05-05 10:05:02 +08:00
|
|
|
// Chosen to match the usual chunk size in a torrent client. This way, most chunk writes are to
|
|
|
|
// exactly one full item in bbolt DB.
|
2016-08-31 19:00:44 +08:00
|
|
|
chunkSize = 1 << 14
|
|
|
|
)
|
2016-08-31 16:04:11 +08:00
|
|
|
|
2021-05-05 10:05:02 +08:00
|
|
|
type boltClient struct {
|
2020-03-24 09:54:57 +08:00
|
|
|
db *bbolt.DB
|
2016-08-31 15:48:50 +08:00
|
|
|
}
|
|
|
|
|
2021-05-05 10:05:02 +08:00
|
|
|
type boltTorrent struct {
|
|
|
|
cl *boltClient
|
2016-08-31 15:48:50 +08:00
|
|
|
ih metainfo.Hash
|
|
|
|
}
|
|
|
|
|
2020-02-21 11:12:44 +08:00
|
|
|
func NewBoltDB(filePath string) ClientImplCloser {
|
2021-11-08 11:47:01 +08:00
|
|
|
db, err := bbolt.Open(filepath.Join(filePath, "bolt.db"), 0o600, &bbolt.Options{
|
2018-01-09 20:11:34 +08:00
|
|
|
Timeout: time.Second,
|
|
|
|
})
|
2018-04-12 09:34:24 +08:00
|
|
|
expect.Nil(err)
|
2018-01-09 20:11:34 +08:00
|
|
|
db.NoSync = true
|
2021-05-05 10:05:02 +08:00
|
|
|
return &boltClient{db}
|
2016-08-31 15:48:50 +08:00
|
|
|
}
|
|
|
|
|
2021-05-05 10:05:02 +08:00
|
|
|
func (me *boltClient) Close() error {
|
2016-10-25 16:07:26 +08:00
|
|
|
return me.db.Close()
|
|
|
|
}
|
|
|
|
|
2021-11-01 08:53:58 +08:00
|
|
|
func (me *boltClient) OpenTorrent(_ *metainfo.Info, infoHash metainfo.Hash) (TorrentImpl, error) {
|
2021-05-09 21:40:44 +08:00
|
|
|
t := &boltTorrent{me, infoHash}
|
|
|
|
return TorrentImpl{
|
|
|
|
Piece: t.Piece,
|
|
|
|
Close: t.Close,
|
|
|
|
}, nil
|
2016-08-31 15:48:50 +08:00
|
|
|
}
|
|
|
|
|
2021-05-05 10:05:02 +08:00
|
|
|
func (me *boltTorrent) Piece(p metainfo.Piece) PieceImpl {
|
|
|
|
ret := &boltPiece{
|
2017-10-12 13:09:32 +08:00
|
|
|
p: p,
|
|
|
|
db: me.cl.db,
|
|
|
|
ih: me.ih,
|
|
|
|
}
|
2016-08-31 15:48:50 +08:00
|
|
|
copy(ret.key[:], me.ih[:])
|
|
|
|
binary.BigEndian.PutUint32(ret.key[20:], uint32(p.Index()))
|
|
|
|
return ret
|
|
|
|
}
|
|
|
|
|
2021-05-05 10:05:02 +08:00
|
|
|
func (boltTorrent) Close() error { return nil }
|