+func iterBitmapsDistinct(skip bitmap.Bitmap, bms ...bitmap.Bitmap) iter.Func {
+ return func(cb iter.Callback) {
+ for _, bm := range bms {
+ if !iter.All(func(i interface{}) bool {
+ skip.Add(i.(int))
+ return cb(i)
+ }, bitmap.Sub(bm, skip).Iter) {
+ return
+ }
+ }
+ }
+}
+
+func (cn *connection) unbiasedPieceRequestOrder() iter.Func {
+ now, readahead := cn.t.readerPiecePriorities()
+ return iterBitmapsDistinct(cn.t.completedPieces.Copy(), now, readahead, cn.t.pendingPieces)
+}
+
+// The connection should download highest priority pieces first, without any
+// inclination toward avoiding wastage. Generally we might do this if there's
+// a single connection, or this is the fastest connection, and we have active
+// readers that signal an ordering preference. It's conceivable that the best
+// connection should do this, since it's least likely to waste our time if
+// assigned to the highest priority pieces, and assigning more than one this
+// role would cause significant wasted bandwidth.
+func (cn *connection) shouldRequestWithoutBias() bool {
+ if cn.t.requestStrategy != 2 {
+ return false
+ }
+ if len(cn.t.readers) == 0 {
+ return false
+ }
+ if len(cn.t.conns) == 1 {
+ return true
+ }
+ if cn == cn.t.fastestConn {
+ return true
+ }
+ return false
+}
+
+func (cn *connection) pieceRequestOrderIter() iter.Func {
+ if cn.shouldRequestWithoutBias() {
+ return cn.unbiasedPieceRequestOrder()
+ } else {
+ return cn.pieceRequestOrder.Iter
+ }
+}
+