]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Set priorities ahead of the current read position
authorMatt Joiner <anacrolix@gmail.com>
Fri, 5 Dec 2014 06:56:28 +0000 (00:56 -0600)
committerMatt Joiner <anacrolix@gmail.com>
Fri, 5 Dec 2014 06:56:28 +0000 (00:56 -0600)
client.go
connection.go
misc.go
torrent.go

index 3361132ae5cb6a7a3d73c2d8f39b9953ed08761b..84a11f59058ba874d5bfb80c1617731c94c6c0c0 100644 (file)
--- a/client.go
+++ b/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()
 }
 
index 1d55dd5732458de86b8d49807f40be1018689702..42b1a75d005e5e94309073b061f27e617efb293d 100644 (file)
@@ -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)
 }
diff --git a/misc.go b/misc.go
index a32404495b18d052067a1d2a2228a70be1654dbd..5ac9d53874f2776bd70242c8a64ecb7566c33be7 100644 (file)
--- a/misc.go
+++ b/misc.go
@@ -43,7 +43,9 @@ type piecePriority byte
 const (
        piecePriorityNone piecePriority = iota
        piecePriorityNormal
-       piecePriorityHigh
+       piecePriorityReadahead
+       piecePriorityNext
+       piecePriorityNow
 )
 
 type piece struct {
index 56b738a8d1d3922632dd669e42890832c31a991b..91e550d9e8b85b9e20364a759b954953b07b72be 100644 (file)
@@ -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 '.'
+               }
        }
 }