Recalculate all piece priorities more efficiently
This commit is contained in:
parent
afa264e6c5
commit
430f26f726
@ -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
|
||||
}
|
||||
}
|
||||
|
6
piece.go
6
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.
|
||||
|
35
torrent.go
35
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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user