Set priorities ahead of the current read position
This commit is contained in:
parent
ac1afa19b8
commit
b6ae4caa6a
34
client.go
34
client.go
|
@ -264,22 +264,36 @@ func (cl *Client) torrentReadAt(t *torrent, off int64, p []byte) (n int, err err
|
|||
err = io.EOF
|
||||
return
|
||||
}
|
||||
cl.readRaisePiecePriorities(t, off, int64(len(p)))
|
||||
if len(p) > pieceLeft {
|
||||
p = p[:pieceLeft]
|
||||
}
|
||||
if len(p) == 0 {
|
||||
panic(len(p))
|
||||
}
|
||||
cl.prioritizePiece(t, index, piecePriorityHigh)
|
||||
for i := index + 1; i < index+7 && i < t.NumPieces(); i++ {
|
||||
cl.prioritizePiece(t, i, piecePriorityNormal)
|
||||
}
|
||||
for !piece.Complete() {
|
||||
piece.Event.Wait()
|
||||
}
|
||||
return t.Data.ReadAt(p, off)
|
||||
}
|
||||
|
||||
func (cl *Client) readRaisePiecePriorities(t *torrent, off, _len int64) {
|
||||
index := int(off / int64(t.UsualPieceSize()))
|
||||
cl.raisePiecePriority(t, index, piecePriorityNow)
|
||||
index++
|
||||
if index >= t.NumPieces() {
|
||||
return
|
||||
}
|
||||
cl.raisePiecePriority(t, index, piecePriorityNext)
|
||||
for i := 0; i < 5; i++ {
|
||||
index++
|
||||
if index >= t.NumPieces() {
|
||||
break
|
||||
}
|
||||
cl.raisePiecePriority(t, index, piecePriorityReadahead)
|
||||
}
|
||||
}
|
||||
|
||||
func (cl *Client) configDir() string {
|
||||
return filepath.Join(os.Getenv("HOME"), ".config/torrent")
|
||||
}
|
||||
|
@ -292,6 +306,12 @@ func (t *torrent) connPendPiece(c *connection, piece int) {
|
|||
c.pendPiece(piece, t.Pieces[piece].Priority)
|
||||
}
|
||||
|
||||
func (cl *Client) raisePiecePriority(t *torrent, piece int, priority piecePriority) {
|
||||
if t.Pieces[piece].Priority < priority {
|
||||
cl.prioritizePiece(t, piece, priority)
|
||||
}
|
||||
}
|
||||
|
||||
func (cl *Client) prioritizePiece(t *torrent, piece int, priority piecePriority) {
|
||||
if t.havePiece(piece) {
|
||||
return
|
||||
|
@ -1595,8 +1615,10 @@ func (t Torrent) DownloadAll() {
|
|||
// TODO: Leave higher priorities as they were?
|
||||
t.cl.prioritizePiece(t.torrent, i, piecePriorityNormal)
|
||||
}
|
||||
t.cl.prioritizePiece(t.torrent, 0, piecePriorityHigh)
|
||||
t.cl.prioritizePiece(t.torrent, t.NumPieces()-1, piecePriorityHigh)
|
||||
// Nice to have the first and last pieces soon for various interactive
|
||||
// purposes.
|
||||
t.cl.prioritizePiece(t.torrent, 0, piecePriorityReadahead)
|
||||
t.cl.prioritizePiece(t.torrent, t.NumPieces()-1, piecePriorityReadahead)
|
||||
t.cl.mu.Unlock()
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"expvar"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
|
@ -94,11 +93,15 @@ func (cn *connection) pendPiece(piece int, priority piecePriority) {
|
|||
return
|
||||
}
|
||||
key := cn.piecePriorities[piece]
|
||||
if priority == piecePriorityHigh {
|
||||
key = -key
|
||||
}
|
||||
if piece == 0 {
|
||||
log.Print(key)
|
||||
// TODO: Have some kind of overlap here, so there's some probabilistic
|
||||
// favouring of higher priority pieces.
|
||||
switch priority {
|
||||
case piecePriorityReadahead:
|
||||
key -= len(cn.piecePriorities)
|
||||
case piecePriorityNext:
|
||||
key -= 2 * len(cn.piecePriorities)
|
||||
case piecePriorityNow:
|
||||
key -= 3 * len(cn.piecePriorities)
|
||||
}
|
||||
cn.pieceRequestOrder.SetPiece(piece, key)
|
||||
}
|
||||
|
|
4
misc.go
4
misc.go
|
@ -43,7 +43,9 @@ type piecePriority byte
|
|||
const (
|
||||
piecePriorityNone piecePriority = iota
|
||||
piecePriorityNormal
|
||||
piecePriorityHigh
|
||||
piecePriorityReadahead
|
||||
piecePriorityNext
|
||||
piecePriorityNow
|
||||
)
|
||||
|
||||
type piece struct {
|
||||
|
|
22
torrent.go
22
torrent.go
|
@ -281,12 +281,26 @@ func (t *torrent) pieceStatusChar(index int) byte {
|
|||
return 'H'
|
||||
case !p.EverHashed:
|
||||
return '?'
|
||||
case p.Priority == piecePriorityHigh:
|
||||
return '!'
|
||||
case t.PiecePartiallyDownloaded(index):
|
||||
return 'P'
|
||||
switch p.Priority {
|
||||
case piecePriorityNone:
|
||||
return 'F' // Forgotten
|
||||
default:
|
||||
return 'P'
|
||||
}
|
||||
default:
|
||||
return '.'
|
||||
switch p.Priority {
|
||||
case piecePriorityNone:
|
||||
return 'z'
|
||||
case piecePriorityNow:
|
||||
return '!'
|
||||
case piecePriorityReadahead:
|
||||
return 'R'
|
||||
case piecePriorityNext:
|
||||
return 'N'
|
||||
default:
|
||||
return '.'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue