}
// The actual value to use as the maximum outbound requests.
-func (rs requestStrategyThree) nominalMaxRequests(cn requestStrategyConnection) (ret int) {
+func (rs requestStrategyDuplicateRequestTimeout) nominalMaxRequests(cn requestStrategyConnection) (ret int) {
expectingTime := int64(cn.totalExpectingTime())
if expectingTime == 0 {
expectingTime = math.MaxInt64
max(64,
cn.stats().ChunksReadUseful.Int64()-(cn.stats().ChunksRead.Int64()-cn.stats().ChunksReadUseful.Int64())))
}
-func (rs requestStrategyOne) nominalMaxRequests(cn requestStrategyConnection) int {
+func (rs requestStrategyFuzzing) nominalMaxRequests(cn requestStrategyConnection) int {
return defaultNominalMaxRequests(cn)
}
-func (rs requestStrategyTwo) nominalMaxRequests(cn requestStrategyConnection) int {
+func (rs requestStrategyFastest) nominalMaxRequests(cn requestStrategyConnection) int {
return defaultNominalMaxRequests(cn)
}
})
}
-func (rs requestStrategyThree) onSentRequest(r request) {
+func (rs requestStrategyDuplicateRequestTimeout) onSentRequest(r request) {
rs.lastRequested[r] = time.AfterFunc(rs.duplicateRequestTimeout, func() {
rs.timeoutLocker.Lock()
delete(rs.lastRequested, r)
return false
}
-func (requestStrategyTwo) shouldRequestWithoutBias(cn requestStrategyConnection) bool {
+func (requestStrategyFastest) shouldRequestWithoutBias(cn requestStrategyConnection) bool {
if cn.torrent().numReaders() == 0 {
return false
}
return false
}
-func (requestStrategyOne) shouldRequestWithoutBias(cn requestStrategyConnection) bool {
+func (requestStrategyFuzzing) shouldRequestWithoutBias(cn requestStrategyConnection) bool {
return defaultShouldRequestWithoutBias(cn)
}
-func (requestStrategyThree) shouldRequestWithoutBias(cn requestStrategyConnection) bool {
+func (requestStrategyDuplicateRequestTimeout) shouldRequestWithoutBias(cn requestStrategyConnection) bool {
return defaultShouldRequestWithoutBias(cn)
}
}
return cn.t.requestStrategy.iterPendingPieces(cn, f)
}
-func (requestStrategyThree) iterPendingPieces(cn requestStrategyConnection, f func(pieceIndex) bool) bool {
+func (requestStrategyDuplicateRequestTimeout) iterPendingPieces(cn requestStrategyConnection, f func(pieceIndex) bool) bool {
return iterUnbiasedPieceRequestOrder(cn, f)
}
func defaultIterPendingPieces(rs requestStrategy, cn requestStrategyConnection, f func(pieceIndex) bool) bool {
})
}
}
-func (rs requestStrategyOne) iterPendingPieces(cn requestStrategyConnection, cb func(pieceIndex) bool) bool {
+func (rs requestStrategyFuzzing) iterPendingPieces(cn requestStrategyConnection, cb func(pieceIndex) bool) bool {
return defaultIterPendingPieces(rs, cn, cb)
}
-func (rs requestStrategyTwo) iterPendingPieces(cn requestStrategyConnection, cb func(pieceIndex) bool) bool {
+func (rs requestStrategyFastest) iterPendingPieces(cn requestStrategyConnection, cb func(pieceIndex) bool) bool {
return defaultIterPendingPieces(rs, cn, cb)
}
)
}
-func (rs requestStrategyThree) iterUndirtiedChunks(p requestStrategyPiece, f func(chunkSpec) bool) bool {
+func (rs requestStrategyDuplicateRequestTimeout) iterUndirtiedChunks(p requestStrategyPiece, f func(chunkSpec) bool) bool {
for i := pp.Integer(0); i < pp.Integer(p.numChunks()); i++ {
if p.dirtyChunks().Get(bitmap.BitIndex(i)) {
continue
})
}
-func (rs requestStrategyOne) iterUndirtiedChunks(p requestStrategyPiece, f func(chunkSpec) bool) bool {
+func (rs requestStrategyFuzzing) iterUndirtiedChunks(p requestStrategyPiece, f func(chunkSpec) bool) bool {
return defaultIterUndirtiedChunks(p, f)
}
-func (rs requestStrategyTwo) iterUndirtiedChunks(p requestStrategyPiece, f func(chunkSpec) bool) bool {
+func (rs requestStrategyFastest) iterUndirtiedChunks(p requestStrategyPiece, f func(chunkSpec) bool) bool {
return defaultIterUndirtiedChunks(p, f)
}
return cn._pieceRequestOrder.Set(bitmap.BitIndex(piece), prio) || cn.shouldRequestWithoutBias()
}
-func (requestStrategyOne) piecePriority(cn requestStrategyConnection, piece pieceIndex, tpp piecePriority, prio int) int {
+func (requestStrategyFuzzing) piecePriority(cn requestStrategyConnection, piece pieceIndex, tpp piecePriority, prio int) int {
switch tpp {
case PiecePriorityNormal:
case PiecePriorityReadahead:
return prio
}
-func (requestStrategyTwo) piecePriority(cn requestStrategyConnection, piece pieceIndex, tpp piecePriority, prio int) int {
+func (requestStrategyFastest) piecePriority(cn requestStrategyConnection, piece pieceIndex, tpp piecePriority, prio int) int {
return defaultPiecePriority(cn, piece, tpp, prio)
}
-func (requestStrategyThree) piecePriority(cn requestStrategyConnection, piece pieceIndex, tpp piecePriority, prio int) int {
+func (requestStrategyDuplicateRequestTimeout) piecePriority(cn requestStrategyConnection, piece pieceIndex, tpp piecePriority, prio int) int {
return defaultPiecePriority(cn, piece, tpp, prio)
}
// Favour higher priority pieces with some fuzzing to reduce overlaps and wastage across
// connections.
-type requestStrategyOne struct {
+type requestStrategyFuzzing struct {
requestStrategyDefaults
}
// The fastest connection downloads strictly in order of priority, while all others adhere to their
// piece inclinations.
-type requestStrategyTwo struct {
+type requestStrategyFastest struct {
requestStrategyDefaults
}
-func (requestStrategyTwo) ShouldRequestWithoutBias(cn requestStrategyConnection) bool {
+func newRequestStrategyMaker(rs requestStrategy) RequestStrategyMaker {
+ return func(requestStrategyCallbacks, sync.Locker) requestStrategy {
+ return rs
+ }
+}
+
+func RequestStrategyFastest() RequestStrategyMaker {
+ return newRequestStrategyMaker(requestStrategyFastest{})
+}
+
+func RequestStrategyFuzzing() RequestStrategyMaker {
+ return newRequestStrategyMaker(requestStrategyFuzzing{})
+}
+
+func (requestStrategyFastest) ShouldRequestWithoutBias(cn requestStrategyConnection) bool {
if cn.torrent().numReaders() == 0 {
return false
}
// Requests are strictly by piece priority, and not duplicated until duplicateRequestTimeout is
// reached.
-type requestStrategyThree struct {
+type requestStrategyDuplicateRequestTimeout struct {
// How long to avoid duplicating a pending request.
duplicateRequestTimeout time.Duration
timeoutLocker sync.Locker
}
-type requestStrategyMaker func(callbacks requestStrategyCallbacks, clientLocker sync.Locker) requestStrategy
+type RequestStrategyMaker func(callbacks requestStrategyCallbacks, clientLocker sync.Locker) requestStrategy
-func requestStrategyThreeMaker(duplicateRequestTimeout time.Duration) requestStrategyMaker {
+func RequestStrategyDuplicateRequestTimeout(duplicateRequestTimeout time.Duration) RequestStrategyMaker {
return func(callbacks requestStrategyCallbacks, clientLocker sync.Locker) requestStrategy {
- return requestStrategyThree{
+ return requestStrategyDuplicateRequestTimeout{
duplicateRequestTimeout: duplicateRequestTimeout,
callbacks: callbacks,
lastRequested: make(map[request]*time.Timer),
}
}
-func (rs requestStrategyThree) hooks() requestStrategyHooks {
+func (rs requestStrategyDuplicateRequestTimeout) hooks() requestStrategyHooks {
return requestStrategyHooks{
deletedRequest: func(r request) {
if t, ok := rs.lastRequested[r]; ok {
},
sentRequest: rs.onSentRequest,
}
-
}