bolt.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. //go:build !noboltdb && !wasm
  2. // +build !noboltdb,!wasm
  3. package storage
  4. import (
  5. "context"
  6. "encoding/binary"
  7. "path/filepath"
  8. "time"
  9. "github.com/anacrolix/missinggo/expect"
  10. "go.etcd.io/bbolt"
  11. "github.com/anacrolix/torrent/metainfo"
  12. )
  13. const (
  14. // Chosen to match the usual chunk size in a torrent client. This way, most chunk writes are to
  15. // exactly one full item in bbolt DB.
  16. chunkSize = 1 << 14
  17. )
  18. type boltClient struct {
  19. db *bbolt.DB
  20. }
  21. type boltTorrent struct {
  22. cl *boltClient
  23. ih metainfo.Hash
  24. }
  25. func NewBoltDB(filePath string) ClientImplCloser {
  26. db, err := bbolt.Open(filepath.Join(filePath, "bolt.db"), 0o600, &bbolt.Options{
  27. Timeout: time.Second,
  28. })
  29. expect.Nil(err)
  30. db.NoSync = true
  31. return &boltClient{db}
  32. }
  33. func (me *boltClient) Close() error {
  34. return me.db.Close()
  35. }
  36. func (me *boltClient) OpenTorrent(
  37. _ context.Context,
  38. _ *metainfo.Info,
  39. infoHash metainfo.Hash,
  40. ) (TorrentImpl, error) {
  41. t := &boltTorrent{me, infoHash}
  42. return TorrentImpl{
  43. Piece: t.Piece,
  44. Close: t.Close,
  45. }, nil
  46. }
  47. func (me *boltTorrent) Piece(p metainfo.Piece) PieceImpl {
  48. ret := &boltPiece{
  49. p: p,
  50. db: me.cl.db,
  51. ih: me.ih,
  52. }
  53. copy(ret.key[:], me.ih[:])
  54. binary.BigEndian.PutUint32(ret.key[20:], uint32(p.Index()))
  55. return ret
  56. }
  57. func (boltTorrent) Close() error { return nil }