2014-06-29 14:22:05 +00:00
|
|
|
package torrent
|
|
|
|
|
|
|
|
import (
|
2014-08-22 07:33:17 +00:00
|
|
|
"io"
|
2014-08-21 11:08:56 +00:00
|
|
|
|
|
|
|
pp "bitbucket.org/anacrolix/go.torrent/peer_protocol"
|
2014-06-29 14:22:05 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type DownloadStrategy interface {
|
2014-12-01 09:36:25 +00:00
|
|
|
// Tops up the outgoing pending requests.
|
|
|
|
FillRequests(*torrent, *connection)
|
2014-08-25 12:14:10 +00:00
|
|
|
TorrentStarted(*torrent)
|
|
|
|
TorrentStopped(*torrent)
|
|
|
|
DeleteRequest(*torrent, request)
|
2014-07-24 03:42:31 +00:00
|
|
|
TorrentPrioritize(t *torrent, off, _len int64)
|
2014-08-25 12:14:10 +00:00
|
|
|
TorrentGotChunk(*torrent, request)
|
2014-07-24 03:42:31 +00:00
|
|
|
TorrentGotPiece(t *torrent, piece int)
|
2014-08-22 07:33:17 +00:00
|
|
|
WriteStatus(w io.Writer)
|
2014-08-23 17:08:11 +00:00
|
|
|
AssertNotRequested(*torrent, request)
|
2014-11-21 06:05:09 +00:00
|
|
|
PendingData(*torrent) bool
|
2014-06-29 14:22:05 +00:00
|
|
|
}
|
|
|
|
|
2014-12-01 09:36:25 +00:00
|
|
|
type DefaultDownloadStrategy struct{}
|
2014-06-29 14:22:05 +00:00
|
|
|
|
2014-11-21 06:05:09 +00:00
|
|
|
func (me *DefaultDownloadStrategy) PendingData(t *torrent) bool {
|
|
|
|
return !t.haveAllPieces()
|
|
|
|
}
|
|
|
|
|
2014-12-01 09:36:25 +00:00
|
|
|
func (me *DefaultDownloadStrategy) AssertNotRequested(t *torrent, r request) {}
|
2014-08-23 17:08:11 +00:00
|
|
|
|
2014-08-22 07:33:17 +00:00
|
|
|
func (me *DefaultDownloadStrategy) WriteStatus(w io.Writer) {}
|
|
|
|
|
2014-12-01 09:36:25 +00:00
|
|
|
func (s *DefaultDownloadStrategy) FillRequests(t *torrent, c *connection) {
|
2014-06-30 14:03:07 +00:00
|
|
|
if c.Interested {
|
|
|
|
if c.PeerChoked {
|
|
|
|
return
|
|
|
|
}
|
2014-12-05 06:58:43 +00:00
|
|
|
if len(c.Requests) > c.requestsLowWater {
|
2014-06-30 14:03:07 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
2014-06-29 14:22:05 +00:00
|
|
|
addRequest := func(req request) (again bool) {
|
2015-02-21 03:54:15 +00:00
|
|
|
if len(c.Requests) >= 32 {
|
|
|
|
return false
|
|
|
|
}
|
2014-12-01 09:36:25 +00:00
|
|
|
return c.Request(req)
|
|
|
|
}
|
2014-12-03 00:22:38 +00:00
|
|
|
for e := c.pieceRequestOrder.First(); e != nil; e = e.Next() {
|
|
|
|
pieceIndex := e.Piece()
|
2014-12-01 09:36:25 +00:00
|
|
|
if !c.PeerHasPiece(pp.Integer(pieceIndex)) {
|
2014-12-03 00:22:38 +00:00
|
|
|
panic("piece in request order but peer doesn't have it")
|
2014-06-29 14:22:05 +00:00
|
|
|
}
|
2014-12-01 09:36:25 +00:00
|
|
|
if !t.wantPiece(pieceIndex) {
|
2014-12-03 00:22:38 +00:00
|
|
|
panic("unwanted piece in connection request order")
|
2014-06-29 14:22:05 +00:00
|
|
|
}
|
2014-12-01 09:36:25 +00:00
|
|
|
piece := t.Pieces[pieceIndex]
|
|
|
|
for _, cs := range piece.shuffledPendingChunkSpecs() {
|
|
|
|
r := request{pp.Integer(pieceIndex), cs}
|
|
|
|
if !addRequest(r) {
|
|
|
|
return
|
2014-06-29 14:22:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-09-14 17:25:53 +00:00
|
|
|
return
|
2014-06-29 14:22:05 +00:00
|
|
|
}
|
|
|
|
|
2014-12-01 09:36:25 +00:00
|
|
|
func (s *DefaultDownloadStrategy) TorrentStarted(t *torrent) {}
|
2014-06-29 14:22:05 +00:00
|
|
|
|
|
|
|
func (s *DefaultDownloadStrategy) TorrentStopped(t *torrent) {
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *DefaultDownloadStrategy) DeleteRequest(t *torrent, r request) {
|
|
|
|
}
|
|
|
|
|
2014-07-24 03:42:31 +00:00
|
|
|
func (me *DefaultDownloadStrategy) TorrentGotChunk(t *torrent, c request) {}
|
|
|
|
func (me *DefaultDownloadStrategy) TorrentGotPiece(t *torrent, piece int) {}
|
|
|
|
func (*DefaultDownloadStrategy) TorrentPrioritize(t *torrent, off, _len int64) {}
|