go cl.verifyPiece(t, pieceIndex)
}
-func (cl *Client) PrioritizeDataRegion(ih InfoHash, off, len_ int64) {
+func (cl *Client) PrioritizeDataRegion(ih InfoHash, off, len_ int64) error {
cl.mu.Lock()
defer cl.mu.Unlock()
t := cl.torrent(ih)
- newPriorities := make([]Request, 0, (len_+2*(chunkSize-1))/chunkSize)
+ if t == nil {
+ return errors.New("no such active torrent")
+ }
+ newPriorities := make([]Request, 0, (len_+chunkSize-1)/chunkSize)
for len_ > 0 {
- // TODO: Write a function to return the Request for a given offset.
req, ok := t.offsetRequest(off)
if !ok {
- break
+ return errors.New("bad offset")
}
- off += int64(req.Length)
+ reqOff := t.requestOffset(req)
+ // Gain the alignment adjustment.
+ len_ += off - reqOff
+ // Lose the length of this block.
len_ -= int64(req.Length)
- // TODO(anacrolix): Determine if this check is satisfactory.
- if _, ok = t.Pieces[req.Index].PendingChunkSpecs[req.ChunkSpec]; !ok {
+ off = reqOff + int64(req.Length)
+ if !t.wantPiece(int(req.Index)) {
continue
}
newPriorities = append(newPriorities, req)
}
if len(newPriorities) == 0 {
- return
+ return nil
}
if t.Priorities == nil {
t.Priorities = list.New()
for _, cn := range t.Conns {
cl.replenishConnRequests(t, cn)
}
+ return nil
}
type DataSpec struct {
infoHash := torrent.BytesInfoHash(fn.metaInfo.InfoHash)
torrentOff := fn.TorrentOffset + req.Offset
log.Print(torrentOff, len(data), fn.TorrentOffset)
- fn.FS.Client.PrioritizeDataRegion(infoHash, torrentOff, int64(len(data)))
+ if err := fn.FS.Client.PrioritizeDataRegion(infoHash, torrentOff, int64(len(data))); err != nil {
+ panic(err)
+ }
for {
dataWaiter := fn.FS.Client.DataWaiter()
n, err := fn.FS.Client.TorrentReadAt(infoHash, torrentOff, data)
}
}
+// TODO(anacrolix): Why should rootNode implement this?
func (rootNode) Forget() {
}
return
}
+func torrentRequestOffset(torrentLength, pieceSize int64, r Request) (off int64) {
+ off = int64(r.Index)*pieceSize + int64(r.Begin)
+ if off < 0 || off >= torrentLength {
+ panic("invalid request")
+ }
+ return
+}
+
+func (t *Torrent) requestOffset(r Request) int64 {
+ return torrentRequestOffset(t.Length(), t.MetaInfo.PieceLength, r)
+}
+
// Return the request that would include the given offset into the torrent data.
func (t *Torrent) offsetRequest(off int64) (req Request, ok bool) {
return torrentOffsetRequest(t.Length(), t.MetaInfo.PieceLength, chunkSize, off)