Order readahead requests by piece index

This commit is contained in:
Matt Joiner 2022-05-06 16:27:43 +10:00
parent a54d2d81e4
commit 7e362c0cb3
No known key found for this signature in database
GPG Key ID: 6B990B8185E7F782
1 changed files with 31 additions and 6 deletions

View File

@ -96,16 +96,31 @@ func (p *desiredPeerRequests) Less(i, j int) bool {
rightPiece := t.piece(rightPieceIndex) rightPiece := t.piece(rightPieceIndex)
// Putting this first means we can steal requests from lesser-performing peers for our first few // Putting this first means we can steal requests from lesser-performing peers for our first few
// new requests. // new requests.
ml = ml.Int( priority := func() piecePriority {
// Technically we would be happy with the cached priority here, except we don't actually // Technically we would be happy with the cached priority here, except we don't actually
// cache it anymore, and Torrent.piecePriority just does another lookup of *Piece to resolve // cache it anymore, and Torrent.piecePriority just does another lookup of *Piece to resolve
// the priority through Piece.purePriority, which is probably slower. // the priority through Piece.purePriority, which is probably slower.
-int(leftPiece.purePriority()), leftPriority := leftPiece.purePriority()
-int(rightPiece.purePriority()), rightPriority := rightPiece.purePriority()
ml = ml.Int(
-int(leftPriority),
-int(rightPriority),
) )
if !ml.Ok() {
if leftPriority != rightPriority {
panic("expected equal")
}
}
return leftPriority
}()
if ml.Ok() {
return ml.MustLess()
}
leftPeer := t.pendingRequests[leftRequest] leftPeer := t.pendingRequests[leftRequest]
rightPeer := t.pendingRequests[rightRequest] rightPeer := t.pendingRequests[rightRequest]
// Prefer chunks already requested from this peer.
ml = ml.Bool(rightPeer == p.peer, leftPeer == p.peer) ml = ml.Bool(rightPeer == p.peer, leftPeer == p.peer)
// Prefer unrequested chunks.
ml = ml.Bool(rightPeer == nil, leftPeer == nil) ml = ml.Bool(rightPeer == nil, leftPeer == nil)
if ml.Ok() { if ml.Ok() {
return ml.MustLess() return ml.MustLess()
@ -128,8 +143,18 @@ func (p *desiredPeerRequests) Less(i, j int) bool {
ml = ml.CmpInt64(rightLast.Sub(leftLast).Nanoseconds()) ml = ml.CmpInt64(rightLast.Sub(leftLast).Nanoseconds())
} }
ml = ml.Int( ml = ml.Int(
int(leftPiece.relativeAvailability), leftPiece.relativeAvailability,
int(rightPiece.relativeAvailability)) rightPiece.relativeAvailability)
if priority == PiecePriorityReadahead {
// TODO: For readahead in particular, it would be even better to consider distance from the
// reader position so that reads earlier in a torrent don't starve reads later in the
// torrent. This would probably require reconsideration of how readahead priority works.
ml = ml.Int(leftPieceIndex, rightPieceIndex)
} else {
// TODO: To prevent unnecessarily requesting from disparate pieces, and to ensure pieces are
// selected randomly when availability is even, there should be some fixed ordering of
// pieces.
}
return ml.Less() return ml.Less()
} }