github.com/anacrolix/torrent@v1.61.0/storage/bolt.go (about)

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