2
0
mirror of synced 2025-02-24 14:48:27 +00:00

Recalculate all piece priorities more efficiently

This commit is contained in:
Matt Joiner 2016-02-01 22:06:13 +11:00
parent afa264e6c5
commit 430f26f726
3 changed files with 31 additions and 15 deletions

View File

@ -1672,8 +1672,9 @@ func (t *torrent) needData() bool {
if !t.haveInfo() { if !t.haveInfo() {
return true return true
} }
for i := t.pendingPieces.Iter(); i.Next(); { for i := t.pendingPieces.IterTyped(); i.Next(); {
if t.wantPiece(i.Value()) { if t.wantPiece(i.ValueInt()) {
i.Stop()
return true return true
} }
} }

View File

@ -13,6 +13,12 @@ import (
type piecePriority byte type piecePriority byte
func (me *piecePriority) Raise(maybe piecePriority) {
if maybe > *me {
*me = maybe
}
}
const ( const (
PiecePriorityNone piecePriority = iota // Not wanted. PiecePriorityNone piecePriority = iota // Not wanted.
PiecePriorityNormal // Wanted. PiecePriorityNormal // Wanted.

View File

@ -14,6 +14,7 @@ import (
"github.com/anacrolix/missinggo" "github.com/anacrolix/missinggo"
"github.com/anacrolix/missinggo/bitmap" "github.com/anacrolix/missinggo/bitmap"
"github.com/anacrolix/missinggo/itertools"
"github.com/anacrolix/missinggo/perf" "github.com/anacrolix/missinggo/perf"
"github.com/anacrolix/missinggo/pubsub" "github.com/anacrolix/missinggo/pubsub"
"github.com/bradfitz/iter" "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 { func (t *torrent) connHasWantedPieces(c *connection) bool {
for it := t.pendingPieces.Iter(); it.Next(); { for it := t.pendingPieces.IterTyped(); it.Next(); {
if c.PeerHasPiece(it.Value()) { if c.PeerHasPiece(it.ValueInt()) {
it.Stop()
return true return true
} }
} }
@ -870,15 +872,26 @@ func (t *torrent) updatePiecePriority(piece int) bool {
} }
func (t *torrent) updatePiecePriorities() { func (t *torrent) updatePiecePriorities() {
for i := range t.Pieces { newPrios := make([]piecePriority, t.numPieces())
if t.updatePiecePriority(i) { 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) t.piecePriorityChanged(i)
} }
} }
for _, c := range t.Conns {
c.updateRequests()
}
t.maybeNewConns()
} }
func (t *torrent) byteRegionPieces(off, size int64) (begin, end int) { 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) { if t.pendingPieces.Contains(piece) {
ret = PiecePriorityNormal ret = PiecePriorityNormal
} }
raiseRet := func(prio piecePriority) { raiseRet := ret.Raise
if prio > ret {
ret = prio
}
}
t.forReaderOffsetPieces(func(begin, end int) (again bool) { t.forReaderOffsetPieces(func(begin, end int) (again bool) {
if piece == begin { if piece == begin {
raiseRet(PiecePriorityNow) raiseRet(PiecePriorityNow)