if _, ok := cn.requests[r]; ok {
panic("chunk already requested")
}
- if !cn.PeerHasPiece(r.Index) {
+ if !cn.PeerHasPiece(pieceIndex(r.Index)) {
panic("requesting piece peer doesn't have")
}
if _, ok := cn.t.conns[cn]; !ok {
chunkIndices := t.pieces[piece].undirtiedChunkIndices().ToSortedSlice()
// TODO: Use "math/rand".Shuffle >= Go 1.10
return iter.ForPerm(len(chunkIndices), func(i int) bool {
- return f(t.chunkIndexSpec(pieceIndex(chunkIndices[i]), piece))
+ return f(t.chunkIndexSpec(pp.Integer(chunkIndices[i]), piece))
})
}
func (c *connection) onReadRequest(r request) error {
requestedChunkLengths.Add(strconv.FormatUint(r.Length.Uint64(), 10), 1)
- if r.Begin+r.Length > c.t.pieceLength(r.Index) {
+ if r.Begin+r.Length > c.t.pieceLength(pieceIndex(r.Index)) {
torrent.Add("bad requests received", 1)
return errors.New("bad request")
}
// BEP 6 says we may close here if we choose.
return nil
}
- if !c.t.havePiece(r.Index) {
+ if !c.t.havePiece(pieceIndex(r.Index)) {
// This isn't necessarily them screwing up. We can drop pieces
// from our storage, and can't communicate this to peers
// except by reconnecting.
// We'll probably choke them for this, which will clear them if
// appropriate, and is clearly specified.
case pp.Have:
- err = c.peerSentHave(msg.Index)
+ err = c.peerSentHave(pieceIndex(msg.Index))
case pp.Request:
r := newRequestFromMessage(&msg)
err = c.onReadRequest(r)
if err != nil {
log.Printf("%s (%s): error writing chunk %v: %s", t, t.infoHash, req, err)
t.pendRequest(req)
- t.updatePieceCompletion(msg.Index)
+ t.updatePieceCompletion(pieceIndex(msg.Index))
return nil
}
// It's important that the piece is potentially queued before we check if
// the piece is still wanted, because if it is queued, it won't be wanted.
- if t.pieceAllDirty(req.Index) {
- t.queuePieceCheck(req.Index)
- t.pendAllChunkSpecs(req.Index)
+ if t.pieceAllDirty(pieceIndex(req.Index)) {
+ t.queuePieceCheck(pieceIndex(req.Index))
+ t.pendAllChunkSpecs(pieceIndex(req.Index))
}
- c.onDirtiedPiece(req.Index)
+ c.onDirtiedPiece(pieceIndex(req.Index))
cl.event.Broadcast()
- t.publishPieceChange(req.Index)
+ t.publishPieceChange(pieceIndex(req.Index))
return nil
}
}
more, err := c.sendChunk(r, msg)
if err != nil {
- i := r.Index
+ i := pieceIndex(r.Index)
if c.t.pieceComplete(i) {
c.t.updatePieceCompletion(i)
if !c.t.pieceComplete(i) {
"strings"
"github.com/anacrolix/torrent/metainfo"
- pwp "github.com/anacrolix/torrent/peer_protocol"
)
// Provides access to regions of torrent data that correspond to its files.
return f.prio
}
-func (f *File) firstPieceIndex() pwp.Integer {
+func (f *File) firstPieceIndex() pieceIndex {
if f.t.usualPieceSize() == 0 {
return 0
}
- return pwp.Integer(f.offset / int64(f.t.usualPieceSize()))
+ return pieceIndex(f.offset / int64(f.t.usualPieceSize()))
}
-func (f *File) endPieceIndex() pwp.Integer {
+func (f *File) endPieceIndex() pieceIndex {
if f.t.usualPieceSize() == 0 {
return 0
}
- return pwp.Integer((f.offset+f.length-1)/int64(f.t.usualPieceSize())) + 1
+ return pieceIndex((f.offset+f.length-1)/int64(f.t.usualPieceSize())) + 1
}
"github.com/anacrolix/torrent/tracker"
)
-func (t *Torrent) chunkIndexSpec(chunkIndex, piece pieceIndex) chunkSpec {
+func (t *Torrent) chunkIndexSpec(chunkIndex pp.Integer, piece pieceIndex) chunkSpec {
return chunkIndexSpec(chunkIndex, t.pieceLength(piece), t.chunkSize)
}
if !t.haveInfo() {
return false
}
- if t.pieceComplete(r.Index) {
+ if t.pieceComplete(pieceIndex(r.Index)) {
return true
}
p := &t.pieces[r.Index]
}
func (t *Torrent) wantPiece(r request) bool {
- if !t.wantPieceIndex(r.Index) {
+ if !t.wantPieceIndex(pieceIndex(r.Index)) {
return false
}
if t.pieces[r.Index].pendingChunk(r.chunkSpec, t.chunkSize) {