- ml := multiless.New().Int(
- peersForPiece[i].requestsInPiece,
- peersForPiece[j].requestsInPiece,
- ).Int(
+ byHasRequest := func() multiless.Computation {
+ ml := multiless.New()
+ if req != nil {
+ _, iHas := peersForPiece[i].nextState.Requests[*req]
+ _, jHas := peersForPiece[j].nextState.Requests[*req]
+ ml = ml.Bool(jHas, iHas)
+ }
+ return ml
+ }()
+ ml := multiless.New()
+ // We always "reallocate", that is force even striping amongst peers that are either on
+ // the last piece they can contribute too, or for pieces marked for this behaviour.
+ // Striping prevents starving peers of requests, and will always re-balance to the
+ // fastest known peers.
+ if !p.alwaysReallocate {
+ ml = ml.Bool(
+ peersForPiece[j].requestablePiecesRemaining == 1,
+ peersForPiece[i].requestablePiecesRemaining == 1)
+ }
+ if p.alwaysReallocate || peersForPiece[j].requestablePiecesRemaining == 1 {
+ ml = ml.Int(
+ peersForPiece[i].requestsInPiece,
+ peersForPiece[j].requestsInPiece)
+ } else {
+ ml = ml.AndThen(byHasRequest)
+ }
+ ml = ml.Int(