}
func (t *torrent) connPendPiece(c *connection, piece int) {
- c.pendPiece(piece, t.Pieces[piece].Priority)
+ c.pendPiece(piece, t.Pieces[piece].Priority, t)
}
func (cl *Client) raisePiecePriority(t *torrent, piece int, priority piecePriority) {
if c.pieceRequestOrder != nil || c.piecePriorities != nil {
panic("double init of request ordering")
}
- c.piecePriorities = mathRand.Perm(t.numPieces())
c.pieceRequestOrder = pieceordering.New()
for i := range iter.N(t.Info.NumPieces()) {
if !c.PeerHasPiece(i) {
func (me *Client) dropConnection(t *torrent, c *connection) {
me.event.Broadcast()
c.Close()
+ if c.piecePriorities != nil {
+ t.connPiecePriorites.Put(c.piecePriorities)
+ // I wonder if it's safe to set it to nil. Probably not. Since it's
+ // only read, it doesn't particularly matter if a closing connection
+ // shares the slice with another connection.
+ }
if me.deleteConnection(t, c) {
me.openNewConns(t)
}
// Adjust piece position in the request order for this connection based on the
// given piece priority.
-func (cn *connection) pendPiece(piece int, priority piecePriority) {
+func (cn *connection) pendPiece(piece int, priority piecePriority, t *torrent) {
if priority == PiecePriorityNone {
cn.pieceRequestOrder.DeletePiece(piece)
return
}
+ if cn.piecePriorities == nil {
+ cn.piecePriorities = t.newConnPiecePriorities()
+ }
pp := cn.piecePriorities[piece]
// Priority regions not to scale. Within each region, piece is randomized
// according to connection.
piecePriorities: []int{1, 4, 0, 3, 2},
}
testRequestOrder(nil, c.pieceRequestOrder, t)
- c.pendPiece(2, PiecePriorityNone)
+ c.pendPiece(2, PiecePriorityNone, nil)
testRequestOrder(nil, c.pieceRequestOrder, t)
- c.pendPiece(1, PiecePriorityNormal)
- c.pendPiece(2, PiecePriorityNormal)
+ c.pendPiece(1, PiecePriorityNormal, nil)
+ c.pendPiece(2, PiecePriorityNormal, nil)
testRequestOrder([]int{2, 1}, c.pieceRequestOrder, t)
- c.pendPiece(0, PiecePriorityNormal)
+ c.pendPiece(0, PiecePriorityNormal, nil)
testRequestOrder([]int{2, 0, 1}, c.pieceRequestOrder, t)
- c.pendPiece(1, PiecePriorityReadahead)
+ c.pendPiece(1, PiecePriorityReadahead, nil)
testRequestOrder([]int{1, 2, 0}, c.pieceRequestOrder, t)
- c.pendPiece(4, PiecePriorityNow)
+ c.pendPiece(4, PiecePriorityNow, nil)
// now(4), r(1), normal(0, 2)
testRequestOrder([]int{4, 1, 2, 0}, c.pieceRequestOrder, t)
- c.pendPiece(2, PiecePriorityReadahead)
+ c.pendPiece(2, PiecePriorityReadahead, nil)
// N(4), R(1, 2), N(0)
testRequestOrder([]int{4, 2, 1, 0}, c.pieceRequestOrder, t)
- c.pendPiece(1, PiecePriorityNow)
+ c.pendPiece(1, PiecePriorityNow, nil)
// now(4, 1), readahead(2), normal(0)
// in the same order, the keys will be: -15+6, -15+12, -5, 1
// so we test that a very low priority (for this connection), "now"
testRequestOrder([]int{4, 2, 1, 0}, c.pieceRequestOrder, t)
// Note this intentially sets to None a piece that's not in the order.
for i := range iter.N(5) {
- c.pendPiece(i, PiecePriorityNone)
+ c.pendPiece(i, PiecePriorityNone, nil)
}
testRequestOrder(nil, c.pieceRequestOrder, t)
}