Add error handling to PrioritizeDataRegion as it's public facing API

This commit is contained in:
Matt Joiner 2014-04-09 01:15:39 +10:00
parent c1bf4de70f
commit 786952e4cd
3 changed files with 30 additions and 9 deletions

View File

@ -33,27 +33,32 @@ func (cl *Client) queuePieceCheck(t *Torrent, pieceIndex peer_protocol.Integer)
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()
@ -65,6 +70,7 @@ func (cl *Client) PrioritizeDataRegion(ih InfoHash, off, len_ int64) {
for _, cn := range t.Conns {
cl.replenishConnRequests(t, cn)
}
return nil
}
type DataSpec struct {

View File

@ -65,7 +65,9 @@ func (fn fileNode) Read(req *fuse.ReadRequest, resp *fuse.ReadResponse, intr fus
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)
@ -217,6 +219,7 @@ func (rootNode) Attr() fuse.Attr {
}
}
// TODO(anacrolix): Why should rootNode implement this?
func (rootNode) Forget() {
}

View File

@ -92,6 +92,18 @@ func torrentOffsetRequest(torrentLength, pieceSize, chunkSize, offset int64) (
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)