diff --git a/connection_test.go b/connection_test.go index f22d26b9..d3c299b0 100644 --- a/connection_test.go +++ b/connection_test.go @@ -86,17 +86,16 @@ func BenchmarkConnectionMainReadLoop(b *testing.B) { cl := &Client{} ts := &torrentStorage{} t := &Torrent{ - cl: cl, - info: &metainfo.Info{ - Pieces: make([]byte, 20), - Length: 1 << 20, - PieceLength: 1 << 20, - }, + cl: cl, storage: &storage.Torrent{ts}, pieceStateChanges: pubsub.NewPubSub(), } + require.NoError(b, t.setInfo(&metainfo.Info{ + Pieces: make([]byte, 20), + Length: 1 << 20, + PieceLength: 1 << 20, + })) t.setChunkSize(defaultChunkSize) - t.makePieces() t.pendingPieces.Set(0, PiecePriorityNormal.BitmapPriority()) r, w := io.Pipe() cn := &connection{ diff --git a/issue97_test.go b/issue97_test.go index 7dc7a322..5ccfa62e 100644 --- a/issue97_test.go +++ b/issue97_test.go @@ -15,17 +15,13 @@ func TestHashPieceAfterStorageClosed(t *testing.T) { td, err := ioutil.TempDir("", "") require.NoError(t, err) defer os.RemoveAll(td) - cs := storage.NewClient(storage.NewFile(td)) - tt := &Torrent{} + tt := &Torrent{ + storageOpener: storage.NewClient(storage.NewFile(td)), + } mi := testutil.GreetingMetaInfo() info, err := mi.UnmarshalInfo() require.NoError(t, err) - tt.info = &info - tt.cacheLength(&info) - tt.initFiles() - tt.makePieces() - tt.storage, err = cs.OpenTorrent(tt.info, mi.HashInfoBytes()) - require.NoError(t, err) + require.NoError(t, tt.setInfo(&info)) require.NoError(t, tt.storage.Close()) tt.hashPiece(0) } diff --git a/torrent.go b/torrent.go index 4d8ace42..f6addaa2 100644 --- a/torrent.go +++ b/torrent.go @@ -334,7 +334,7 @@ func pieceEndFileIndex(pieceEndOffset int64, files []*File) int { return 0 } -func (t *Torrent) cacheLength(info *metainfo.Info) { +func (t *Torrent) cacheLength() { var l int64 for _, f := range t.info.UpvertedFiles() { l += f.Length @@ -342,37 +342,26 @@ func (t *Torrent) cacheLength(info *metainfo.Info) { t.length = &l } -// Called when metadata for a torrent becomes available. -func (t *Torrent) setInfoBytes(b []byte) error { - if t.haveInfo() { - return nil - } - if metainfo.HashBytes(b) != t.infoHash { - return errors.New("info bytes have wrong hash") - } - var info metainfo.Info - err := bencode.Unmarshal(b, &info) - if err != nil { - return fmt.Errorf("error unmarshalling info bytes: %s", err) - } - err = validateInfo(&info) - if err != nil { +func (t *Torrent) setInfo(info *metainfo.Info) error { + if err := validateInfo(info); err != nil { return fmt.Errorf("bad info: %s", err) } - defer t.updateWantPeersEvent() - t.info = &info - t.initFiles() - t.displayName = "" // Save a few bytes lol. - t.cl.event.Broadcast() - t.gotMetainfo.Set() - t.storage, err = t.storageOpener.OpenTorrent(t.info, t.infoHash) - if err != nil { - return fmt.Errorf("error opening torrent storage: %s", err) + if t.storageOpener != nil { + var err error + t.storage, err = t.storageOpener.OpenTorrent(info, t.infoHash) + if err != nil { + return fmt.Errorf("error opening torrent storage: %s", err) + } } - t.cacheLength(&info) - t.metadataBytes = b - t.metadataCompletedChunks = nil + t.info = info + t.displayName = "" // Save a few bytes lol. + t.initFiles() + t.cacheLength() t.makePieces() + return nil +} + +func (t *Torrent) onSetInfo() { for conn := range t.conns { if err := conn.setNumPieces(t.numPieces()); err != nil { log.Printf("closing connection: %s", err) @@ -387,6 +376,26 @@ func (t *Torrent) setInfoBytes(b []byte) error { t.queuePieceCheck(i) } } + t.cl.event.Broadcast() + t.gotMetainfo.Set() + t.updateWantPeersEvent() +} + +// Called when metadata for a torrent becomes available. +func (t *Torrent) setInfoBytes(b []byte) error { + if metainfo.HashBytes(b) != t.infoHash { + return errors.New("info bytes have wrong hash") + } + var info metainfo.Info + if err := bencode.Unmarshal(b, &info); err != nil { + return fmt.Errorf("error unmarshalling info bytes: %s", err) + } + if err := t.setInfo(&info); err != nil { + return err + } + t.metadataBytes = b + t.metadataCompletedChunks = nil + t.onSetInfo() return nil } diff --git a/torrent_test.go b/torrent_test.go index 39575dcc..0f70cb97 100644 --- a/torrent_test.go +++ b/torrent_test.go @@ -75,13 +75,17 @@ func TestTorrentString(t *testing.T) { // a large torrent with small pieces had a lot of overhead in recalculating // piece priorities everytime a reader (possibly in another Torrent) changed. func BenchmarkUpdatePiecePriorities(b *testing.B) { + const ( + numPieces = 13410 + pieceLength = 256 << 10 + ) cl := &Client{} t := cl.newTorrent(metainfo.Hash{}, nil) - t.info = &metainfo.Info{ - Pieces: make([]byte, 20*13410), - PieceLength: 256 << 10, - } - t.makePieces() + require.NoError(b, t.setInfo(&metainfo.Info{ + Pieces: make([]byte, metainfo.HashSize*numPieces), + PieceLength: pieceLength, + Length: pieceLength * numPieces, + })) assert.EqualValues(b, 13410, t.numPieces()) for range iter.N(7) { r := t.NewReader()