"sync"
"time"
+ "github.com/bradfitz/iter"
+
"bitbucket.org/anacrolix/go.torrent/data"
pp "bitbucket.org/anacrolix/go.torrent/peer_protocol"
"bitbucket.org/anacrolix/go.torrent/tracker"
"github.com/anacrolix/libtorgo/metainfo"
)
-func (t *torrent) PieceNumPendingBytes(index pp.Integer) (count pp.Integer) {
- piece := t.Pieces[index]
- if piece.complete {
+func (t *torrent) PieceNumPendingBytes(index int) (count pp.Integer) {
+ if t.pieceComplete(index) {
return 0
}
+ piece := t.Pieces[index]
if !piece.EverHashed {
return t.PieceLength(index)
}
Pieces []*piece
length int64
- data data.Data
+ data StatefulData
Info *metainfo.Info
// Active peer connections.
pruneTimer *time.Timer
}
+func (t *torrent) pieceComplete(piece int) bool {
+ // TODO: This is called when setting metadata, and before storage is
+ // assigned, which doesn't seem right.
+ return t.data != nil && t.data.PieceComplete(piece)
+}
+
// A file-like handle to torrent data that implements SectionOpener. Opened
// sections will be reused so long as Reads and ReadAt's are contiguous.
type handle struct {
if c, ok := t.data.(io.Closer); ok {
c.Close()
}
- t.data = td
- if sd, ok := t.data.(StatefulData); ok {
- for i, p := range t.Pieces {
- p.complete = sd.PieceComplete(i)
- }
+ if sd, ok := td.(StatefulData); ok {
+ t.data = sd
+ } else {
+ t.data = &statelessDataWrapper{td, make([]bool, t.Info.NumPieces())}
}
return
}
func (t *torrent) pieceStatusChar(index int) byte {
p := t.Pieces[index]
switch {
- case p.Complete():
+ case t.pieceComplete(index):
return 'C'
case p.QueuedForHash:
return 'Q'
}
func (t *torrent) numPiecesCompleted() (num int) {
- for _, p := range t.Pieces {
- if p.Complete() {
+ for i := range iter.N(t.Info.NumPieces()) {
+ if t.pieceComplete(i) {
num++
}
}
if !t.haveInfo() {
return false
}
- for _, piece := range t.Pieces {
- if !piece.Complete() {
+ for i := range t.Pieces {
+ if !t.pieceComplete(i) {
return false
}
}
}
func (me *torrent) haveAnyPieces() bool {
- for _, piece := range me.Pieces {
- if piece.Complete() {
+ for i := range me.Pieces {
+ if me.pieceComplete(i) {
return true
}
}
}
func (t *torrent) havePiece(index int) bool {
- return t.haveInfo() && t.Pieces[index].Complete()
+ return t.haveInfo() && t.pieceComplete(index)
}
func (t *torrent) haveChunk(r request) bool {
return false
}
p := t.Pieces[index]
- return p.EverHashed && len(p.PendingChunkSpecs) != 0 && p.Priority != piecePriorityNone
+ return !t.pieceComplete(index) && p.Priority != piecePriorityNone && !p.QueuedForHash && !p.Hashing
}
func (t *torrent) connHasWantedPieces(c *connection) bool {