From 1cfd6ecdcb61be39a05904ea67522899f66e7cb9 Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Sun, 14 Sep 2014 04:03:23 +1000 Subject: [PATCH] Improvements arising from attempting to delay piece hashing until necessary --- client.go | 14 ++++++++++---- download_strategies.go | 23 +++++++++++++++++++---- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/client.go b/client.go index 406f5dde..61556967 100644 --- a/client.go +++ b/client.go @@ -631,7 +631,7 @@ func (me *Client) peerGotPiece(t *torrent, c *connection, piece int) { c.PeerPieces = append(c.PeerPieces, false) } c.PeerPieces[piece] = true - if t.wantPiece(piece) { + if !t.havePiece(piece) { me.replenishConnRequests(t, c) } } @@ -1482,11 +1482,17 @@ func (me *Client) pieceHashed(t *torrent, piece pp.Integer, correct bool) { Index: pp.Integer(piece), }) // TODO: Cancel requests for this piece. - } else { - if conn.PeerHasPiece(piece) { - me.replenishConnRequests(t, conn) + for r := range conn.Requests { + if r.Index == piece { + panic("wat") + } } } + // Do this even if the piece is correct because new first-hashings may + // need to be scheduled. + if conn.PeerHasPiece(piece) { + me.replenishConnRequests(t, conn) + } } if t.haveAllPieces() && me.noUpload { t.CeaseNetworking() diff --git a/download_strategies.go b/download_strategies.go index 0c3af687..569ea381 100644 --- a/download_strategies.go +++ b/download_strategies.go @@ -167,6 +167,9 @@ func (me *requestFiller) request(req request) bool { if me.c.RequestPending(req) { return true } + if !me.t.wantChunk(req) { + return true + } again := me.c.Request(req) if me.c.RequestPending(req) { me.s.requestHeat[me.t][req]++ @@ -186,6 +189,7 @@ func (me *requestFiller) conservativelyRequest(req request) bool { // Fill priority requests. func (me *requestFiller) priorities() bool { for req := range me.s.priorities[me.t] { + // TODO: Perhaps this filter should be applied to every request? if _, ok := me.t.Pieces[req.Index].PendingChunkSpecs[req.chunkSpec]; !ok { panic(req) } @@ -217,6 +221,7 @@ func (me requestFiller) Run() { func (me *requestFiller) completePartial() bool { t := me.t th := me.s.requestHeat[t] + lro, lroOk := me.s.lastReadOffset[t] for e := t.IncompletePiecesByBytesLeft.Front(); e != nil; e = e.Next() { p := e.Value.(int) // Stop when we reach pieces that aren't partial and aren't smaller @@ -224,14 +229,22 @@ func (me *requestFiller) completePartial() bool { if !t.PiecePartiallyDownloaded(p) && int(t.PieceLength(pp.Integer(p))) == t.UsualPieceSize() { break } + // Skip pieces that are entirely inside the readahead zone. + if lroOk { + pieceOff := int64(p) * int64(t.UsualPieceSize()) + pieceEndOff := pieceOff + int64(t.PieceLength(pp.Integer(p))) + if pieceOff >= lro && pieceEndOff < lro+me.s.Readahead { + continue + } + } for chunkSpec := range t.Pieces[p].PendingChunkSpecs { r := request{pp.Integer(p), chunkSpec} if th[r] >= 1 { continue } - if lastReadOffset, ok := me.s.lastReadOffset[t]; ok { + if lroOk { off := me.t.requestOffset(r) - if off >= lastReadOffset && off < lastReadOffset+me.s.Readahead { + if off >= lro && off < lro+me.s.Readahead { continue } } @@ -289,7 +302,9 @@ func (me *requestFiller) readahead() bool { if len(rr) == 0 { return true } - // Produce a partially sorted random permutation into the readahead chunks to somewhat preserve order but reducing wasted chunks due to overlap with other peers. + // Produce a partially sorted random permutation into the readahead chunks + // to somewhat preserve order but reducing wasted chunks due to overlap + // with other peers. ii := new(intHeap) *ii = me.s.rand.Perm(len(rr)) heap.Init(ii) @@ -328,7 +343,7 @@ func (s *responsiveDownloadStrategy) TorrentPrioritize(t *torrent, off, _len int // Lose the length of this block. _len -= int64(req.Length) off = reqOff + int64(req.Length) - if t.wantChunk(req) { + if !t.haveChunk(req) { s.priorities[t][req] = struct{}{} } } -- 2.48.1