storage/boltPieceCompletion.go | 2 +- storage/boltpc_test.go | 2 +- storage/completion.go | 8 ++++---- storage/completion_piece_map.go | 6 +++++- storage/file.go | 16 ++++++++++++---- storage/mmap.go | 12 ++++++++---- diff --git a/storage/boltPieceCompletion.go b/storage/boltPieceCompletion.go index 1b5e18a1955e3af33bfb2ad49908f527578e5967..510e283459063e6914b310d18a7d7b882cf91630 100644 --- a/storage/boltPieceCompletion.go +++ b/storage/boltPieceCompletion.go @@ -18,7 +18,7 @@ type boltPieceCompletion struct { 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, diff --git a/storage/boltpc_test.go b/storage/boltpc_test.go index e1be2579bdf95b469f92499604d226e6268e1202..3f5572e711ae97316fe5c5c4a230679975a5b270 100644 --- a/storage/boltpc_test.go +++ b/storage/boltpc_test.go @@ -16,7 +16,7 @@ td, err := ioutil.TempDir("", "") require.NoError(t, err) defer os.RemoveAll(td) - pc, err := newBoltPieceCompletion(td) + pc, err := NewBoltPieceCompletion(td) require.NoError(t, err) defer pc.Close() diff --git a/storage/completion.go b/storage/completion.go index 7804351036a238c25b9a3b0ddf06ae312d492dcc..c464a0a7b5e06dfad2aaa1a0c852012a251bf67e 100644 --- a/storage/completion.go +++ b/storage/completion.go @@ -7,17 +7,17 @@ "github.com/anacrolix/torrent/metainfo" ) // 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 } diff --git a/storage/completion_piece_map.go b/storage/completion_piece_map.go index f4b4e28582d0744b7e46e2c913436c1d323b8187..ebd98259edebbaeb5a7472758b63059a759027ba 100644 --- a/storage/completion_piece_map.go +++ b/storage/completion_piece_map.go @@ -11,7 +11,11 @@ mu sync.Mutex 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() diff --git a/storage/file.go b/storage/file.go index b0a9ca1034ec933973cd989fe9b72f6f49e925b0..f4ab0913c4aa6d7b17130d822c138e3253e7991c 100644 --- a/storage/file.go +++ b/storage/file.go @@ -15,7 +15,7 @@ // torrent. 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 @@ -29,7 +29,11 @@ } // 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 @@ -39,13 +43,17 @@ } // 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, } } @@ -72,7 +80,7 @@ type fileTorrentImpl struct { dir string info *metainfo.Info infoHash metainfo.Hash - completion pieceCompletion + completion PieceCompletion } func (fts *fileTorrentImpl) Piece(p metainfo.Piece) PieceImpl { diff --git a/storage/mmap.go b/storage/mmap.go index 8cc5a7d573341d386ae4f07344c63b66dac7810d..bbc9ed03f3938d424ae134bc1be6972dc9ec66c1 100644 --- a/storage/mmap.go +++ b/storage/mmap.go @@ -15,13 +15,17 @@ ) 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, } } @@ -40,7 +44,7 @@ } type mmapTorrentStorage struct { span mmap_span.MMapSpan - pc pieceCompletion + pc PieceCompletion } func (ts *mmapTorrentStorage) Piece(p metainfo.Piece) PieceImpl { @@ -58,7 +62,7 @@ return ts.span.Close() } type mmapStoragePiece struct { - pc pieceCompletion + pc PieceCompletion p metainfo.Piece ih metainfo.Hash io.ReaderAt