db *bolt.DB
}
-func newBoltPieceCompletion(dir string) (ret *boltPieceCompletion, err error) {
+func NewBoltPieceCompletion(dir string) (ret PieceCompletion, err error) {
p := filepath.Join(dir, ".torrent.bolt.db")
db, err := bolt.Open(p, 0660, &bolt.Options{
Timeout: time.Second,
require.NoError(t, err)
defer os.RemoveAll(td)
- pc, err := newBoltPieceCompletion(td)
+ pc, err := NewBoltPieceCompletion(td)
require.NoError(t, err)
defer pc.Close()
)
// Implementations track the completion of pieces. It must be concurrent-safe.
-type pieceCompletion interface {
+type PieceCompletion interface {
Get(metainfo.PieceKey) (bool, error)
Set(metainfo.PieceKey, bool) error
Close() error
}
-func pieceCompletionForDir(dir string) (ret pieceCompletion) {
- ret, err := newBoltPieceCompletion(dir)
+func pieceCompletionForDir(dir string) (ret PieceCompletion) {
+ ret, err := NewBoltPieceCompletion(dir)
if err != nil {
log.Printf("couldn't open piece completion db in %q: %s", dir, err)
- ret = new(mapPieceCompletion)
+ ret = NewMapPieceCompletion()
}
return
}
m map[metainfo.PieceKey]struct{}
}
-func (mapPieceCompletion) Close() error { return nil }
+func NewMapPieceCompletion() PieceCompletion {
+ return &mapPieceCompletion{m: make(map[metainfo.PieceKey]struct{})}
+}
+
+func (*mapPieceCompletion) Close() error { return nil }
func (me *mapPieceCompletion) Get(pk metainfo.PieceKey) (bool, error) {
me.mu.Lock()
type fileClientImpl struct {
baseDir string
pathMaker func(baseDir string, info *metainfo.Info, infoHash metainfo.Hash) string
- pc pieceCompletion
+ pc PieceCompletion
}
// The Default path maker just returns the current path
// All Torrent data stored in this baseDir
func NewFile(baseDir string) ClientImpl {
- return NewFileWithCustomPathMaker(baseDir, nil)
+ return NewFileWithCompletion(baseDir, pieceCompletionForDir(baseDir))
+}
+
+func NewFileWithCompletion(baseDir string, completion PieceCompletion) ClientImpl {
+ return newFileWithCustomPathMakerAndCompletion(baseDir, nil, completion)
}
// All Torrent data stored in subdirectorys by infohash
// Allows passing a function to determine the path for storing torrent data
func NewFileWithCustomPathMaker(baseDir string, pathMaker func(baseDir string, info *metainfo.Info, infoHash metainfo.Hash) string) ClientImpl {
+ return newFileWithCustomPathMakerAndCompletion(baseDir, pathMaker, pieceCompletionForDir(baseDir))
+}
+
+func newFileWithCustomPathMakerAndCompletion(baseDir string, pathMaker func(baseDir string, info *metainfo.Info, infoHash metainfo.Hash) string, completion PieceCompletion) ClientImpl {
if pathMaker == nil {
pathMaker = defaultPathMaker
}
return &fileClientImpl{
baseDir: baseDir,
pathMaker: pathMaker,
- pc: pieceCompletionForDir(baseDir),
+ pc: completion,
}
}
dir string
info *metainfo.Info
infoHash metainfo.Hash
- completion pieceCompletion
+ completion PieceCompletion
}
func (fts *fileTorrentImpl) Piece(p metainfo.Piece) PieceImpl {
type mmapStorage struct {
baseDir string
- pc pieceCompletion
+ pc PieceCompletion
}
func NewMMap(baseDir string) ClientImpl {
+ return NewMMapWithCompletion(baseDir, pieceCompletionForDir(baseDir))
+}
+
+func NewMMapWithCompletion(baseDir string, completion PieceCompletion) ClientImpl {
return &mmapStorage{
baseDir: baseDir,
- pc: pieceCompletionForDir(baseDir),
+ pc: completion,
}
}
type mmapTorrentStorage struct {
span mmap_span.MMapSpan
- pc pieceCompletion
+ pc PieceCompletion
}
func (ts *mmapTorrentStorage) Piece(p metainfo.Piece) PieceImpl {
}
type mmapStoragePiece struct {
- pc pieceCompletion
+ pc PieceCompletion
p metainfo.Piece
ih metainfo.Hash
io.ReaderAt