From 430f26f726f92bd475044337888067f7d07fa8d1 Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Mon, 1 Feb 2016 22:06:13 +1100 Subject: [PATCH] Recalculate all piece priorities more efficiently --- client.go | 5 +++-- piece.go | 6 ++++++ torrent.go | 35 ++++++++++++++++++++++------------- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/client.go b/client.go index 2def4f90..8a611bae 100644 --- a/client.go +++ b/client.go @@ -1672,8 +1672,9 @@ func (t *torrent) needData() bool { if !t.haveInfo() { return true } - for i := t.pendingPieces.Iter(); i.Next(); { - if t.wantPiece(i.Value()) { + for i := t.pendingPieces.IterTyped(); i.Next(); { + if t.wantPiece(i.ValueInt()) { + i.Stop() return true } } diff --git a/piece.go b/piece.go index 843ddb9e..16f20653 100644 --- a/piece.go +++ b/piece.go @@ -13,6 +13,12 @@ import ( type piecePriority byte +func (me *piecePriority) Raise(maybe piecePriority) { + if maybe > *me { + *me = maybe + } +} + const ( PiecePriorityNone piecePriority = iota // Not wanted. PiecePriorityNormal // Wanted. diff --git a/torrent.go b/torrent.go index b50db665..48fce3ff 100644 --- a/torrent.go +++ b/torrent.go @@ -14,6 +14,7 @@ import ( "github.com/anacrolix/missinggo" "github.com/anacrolix/missinggo/bitmap" + "github.com/anacrolix/missinggo/itertools" "github.com/anacrolix/missinggo/perf" "github.com/anacrolix/missinggo/pubsub" "github.com/bradfitz/iter" @@ -762,8 +763,9 @@ func (t *torrent) forNeededPieces(f func(piece int) (more bool)) (all bool) { } func (t *torrent) connHasWantedPieces(c *connection) bool { - for it := t.pendingPieces.Iter(); it.Next(); { - if c.PeerHasPiece(it.Value()) { + for it := t.pendingPieces.IterTyped(); it.Next(); { + if c.PeerHasPiece(it.ValueInt()) { + it.Stop() return true } } @@ -870,15 +872,26 @@ func (t *torrent) updatePiecePriority(piece int) bool { } func (t *torrent) updatePiecePriorities() { - for i := range t.Pieces { - if t.updatePiecePriority(i) { + newPrios := make([]piecePriority, t.numPieces()) + itertools.ForIterable(&t.pendingPieces, func(value interface{}) (next bool) { + newPrios[value.(int)] = PiecePriorityNormal + return true + }) + t.forReaderOffsetPieces(func(begin, end int) (next bool) { + if begin < end { + newPrios[begin].Raise(PiecePriorityNow) + } + for i := begin + 1; i < end; i++ { + newPrios[begin].Raise(PiecePriorityReadahead) + } + return true + }) + for i, prio := range newPrios { + if prio != t.Pieces[i].priority { + t.Pieces[i].priority = prio t.piecePriorityChanged(i) } } - for _, c := range t.Conns { - c.updateRequests() - } - t.maybeNewConns() } func (t *torrent) byteRegionPieces(off, size int64) (begin, end int) { @@ -935,11 +948,7 @@ func (t *torrent) piecePriorityUncached(piece int) (ret piecePriority) { if t.pendingPieces.Contains(piece) { ret = PiecePriorityNormal } - raiseRet := func(prio piecePriority) { - if prio > ret { - ret = prio - } - } + raiseRet := ret.Raise t.forReaderOffsetPieces(func(begin, end int) (again bool) { if piece == begin { raiseRet(PiecePriorityNow) -- 2.44.0