def complete(self, event = None): filename = self.fileInfoPanel.dirCtl.GetValue() if filename == '': dlg = wx.MessageDialog(self, message = self.utility.lang.get('youmustselectfileordir'), caption = self.utility.lang.get('error'), style = wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return params = self.fileInfoPanel.getParams() params = union(params, self.trackerInfoPanel.getParams()) params = union(params, self.miscInfoPanel.getParams()) try: CompleteDir(self, filename, params['announce'], params) except: oldstdout = sys.stdout sys.stdout = sys.stderr print_exc() sys.stdout = oldstdout
def CalculateBandwidth(self, dir = "up"): if dir == "up": workingset = union(self.utility.torrents["downloading"], self.utility.torrents["seeding"]) else: workingset = self.utility.torrents["downloading"] # Limit working set to active torrents with connections: workingset = [torrent for torrent in workingset if torrent.status.isActive() and torrent.connection.engine.hasConnections] # No active file, not need to calculate if not workingset: return maxrate = self.MaxRate(dir) # See if global rate settings are set to unlimited if maxrate == 0: # Unlimited rate for torrent in workingset: torrent.connection.maxrate[dir] = torrent.connection.getLocalRate(dir) torrent.connection.setRate(torrent.connection.maxrate[dir], dir) return #print "====================== BEGINNING ALGO ======= th1=%.1f ; th2=%.1f =============================" % (self.calcupth1, self.calcupth2) ####################################################### # - Find number of completed/incomplete torrent # - Number of torrent using local setting # - bandwidth already used by torrents # - Sorting of torrents in lists according to their will in matter of upload rate : # (tobelowered, toberaisedinpriority, toberaised, nottobechanged) ####################################################### # Option set in Preferences/Queue. # If not set, torrents with rate local settings are treated like other torrents, except they have their # own max rate they can't cross over. The consequence is a behaviour slightly different from the behavior of # ABC releases prior to 2.7.0. # If set, this gives the algorithm the behaviour of ABC releases prior to 2.7.0 : the torrents with an rate # local setting will be granted bandwidth in priority to fulfill their local setting, even is this one # is higher than the global max rate setting, and even if this bandwidth must be taken from other active # torrents wihout a local rate setting. These torrents will not take part in the rate exchange # between active torrents when all bandwidth has been distributed, since they will have been served in priority. prioritizelocal = self.utility.config.Read('prioritizelocal', "boolean") # torrents with local rate settings when prioritizelocal is set (see prioritizelocal) localprioactive = [] # torrents for which measured rate is lowering and so reserved rate can be lowered tobelowered = [] # torrents for which measured rate is growing and so reserved rate can be raised, # (with reserved rate > 3 kB/s for uploading) toberaised = [] # torrents for which reserved rate can be raised, with reserved rate < 3 kB/s # These will always be raised even there's no available up bandwith, to fulfill the min 3 kB/s rate rule toberaisedinpriority = [] # torrents for which reserved rate is not to be changed and is > rateminimum; (for these, the # measured rate is between (max upload reserved - calcupth1) and (max upload reserved - calcupth2) nottobechanged = [] meanrate = 0.0 # mean max rate for torrents to be raised or not to be changed ; it will be used to decide which torrents # must be raised amongst those that want to get higher and that must share the available up bandwidth. The torrents # that don't want to change their rate and that are below 3 kB/s are not taken into account on purpose, because # these ones will never be lowered to give more rate to a torrent that wants to raise its rate, or to # compensate for the rate given to torrents to be raised in priority. for torrent in workingset: # Active Torrent currentrate = torrent.connection.rate[dir] maxrate_float = torrent.connection.maxrate[dir] # Torrents dispatch if prioritizelocal and torrent.connection.getLocalRate(dir, True): localprioactive.append(torrent) elif currentrate < 0.05: # These are the torrents that don't want to have their rate changed and that have an allmost null rate # They will not go lower, we can reset their reserved rate until they want to get higher torrent.connection.maxrate[dir] = 0.0 elif maxrate_float - currentrate > self.calcupth1: tobelowered.append(torrent) elif maxrate_float - currentrate <= self.calcupth2: if currentrate < self.rateminimum[dir]: toberaisedinpriority.append(torrent) else: toberaised.append(torrent) meanrate += maxrate_float elif currentrate > self.rateminimum[dir]: nottobechanged.append(torrent) meanrate += maxrate_float # print "index: %i ; rate: %.1f ; reserved: %.1f ; maxlocal: %.1f" % (torrent.listindex, \ # currentrate, maxrate_float, float(torrent.connection.maxlocalrate[dir])) ############################################### # Calculate rate for each torrent ############################################### availableratetobedistributed = maxrate if ((availableratetobedistributed != 0) and (1 - (self.queue.totals_kb[dir] / availableratetobedistributed) > 0.20)): #print "FREE WHEELING TORRENTS" # If there's still at least 20% of available bandwidth, let the torrents do want they want # Keep a reserved max rate updated not to have to reinitilize it when we'll switch later # from free wheeling to controlled status. # Give BitTornado the highest possible value for max rate to speed up the rate rising for torrent in workingset: newrate = torrent.connection.rate[dir] + self.meancalcupth maxlocalrate = float(torrent.connection.getLocalRate(dir)) if maxlocalrate > 0: rateToUse = maxlocalrate if newrate > maxlocalrate: newrate = maxlocalrate else: rateToUse = self.MaxRate(dir) torrent.connection.maxrate[dir] = newrate # Send to BitTornado torrent.connection.setRate(rateToUse, dir) return ########################################################################### # First treat special torrents before going on sharing and distributing ########################################################################### # Treat in priority the torrents with rate below 3 kB/s and that want to get a higher rate grantedfortoberaisedinpriority = 0.0 for torrent in toberaisedinpriority: newreservedrate = torrent.connection.rate[dir] + self.meancalcupth if newreservedrate > self.rateminimum[dir]: grantedfortoberaisedinpriority += self.rateminimum[dir] - torrent.connection.maxrate[dir] torrent.connection.maxrate[dir] = self.rateminimum[dir] else: grantedfortoberaisedinpriority += newreservedrate - torrent.connection.maxrate[dir] torrent.connection.maxrate[dir] = newreservedrate # Treat in priority the torrents with a local rate setting if "prioritize local" is set # As with the free wheeling torrents, keep on tracking the real value of rate while giving BitTornado # the highest max rate to speed up the rate rising. grantedforlocaltoberaised = 0.0 for torrent in localprioactive: newrate = torrent.connection.rate[dir] + self.meancalcupth maxlocalrate = float(torrent.connection.getLocalRate(dir)) if newrate > maxlocalrate: newrate = maxlocalrate grantedforlocaltoberaised += newrate - torrent.connection.maxrate[dir] torrent.connection.maxrate[dir] = newrate # Send to BitTornado torrent.connection.setRate(maxlocalrate, dir) # Torrents that want to be lowered in rate (and give back some reserved bandwidth) givenbackbytobelowered = 0.0 for torrent in tobelowered: newreservedrate = torrent.connection.rate[dir] + self.meancalcupth givenbackbytobelowered += newreservedrate - torrent.connection.maxrate[dir] torrent.connection.maxrate[dir] = newreservedrate # Add to available rate to be distributed the rate given back by the torrents that have been lowered ; # Substract from available rate the rate used for each torrent that have been be raised in priority (torrents with rate # below 3 kB/s and that want to get higher). availableratetobedistributed += givenbackbytobelowered - grantedfortoberaisedinpriority - grantedforlocaltoberaised - self.queue.totals_kb[dir] #print "availableratetobedistributed is %.3f" % availableratetobedistributed # localprioactive torrents have already been updated if prioritizelocal is set toberegulated = [torrent for torrent in workingset if torrent not in localprioactive] # There's nothing to do if no torrent want to be raised if not toberaised: ################################################ # Set new max rate to all active torrents ################################################ for torrent in toberegulated: torrent.connection.setRate(torrent.connection.maxrate[dir], dir) return if availableratetobedistributed > 0: ########################################################################### #print "PHASE 1" ########################################################################### # Phase 1 : As long as there's available bandwidth below the total max to be distributed, I give some # to any torrents that asks for it. # There's a special case with torrents to be raised that have a local max rate : they must be topped to their max local # rate and the surplus part of the reserved bandwidth may be reused. # To sum up : In Phase 1, the measured rate is leading the reserved rate. # Check if all torrents that claim a higher reserved rate will be satisfied claimedrate = 0.0 for torrent in toberaised: maxup = torrent.connection.maxrate[dir] newreservedrate = torrent.connection.rate[dir] + self.meancalcupth toadd = newreservedrate maxlocalup = float(torrent.connection.getLocalRate(dir)) if maxlocalup > 0 and newreservedrate > maxlocalup: toadd = maxlocalup claimedrate += toadd - maxup #print "Claimed rate :", claimedrate #print "Available rate :", availableratetobedistributed if claimedrate <= availableratetobedistributed: realupfactor = 1 else: realupfactor = availableratetobedistributed / claimedrate # If all claims can be fulfilled ; we distribute and go to end. # If there's not enough remaining rate to fulfill all claims, the remaining available rate will be # distributed proportionally between all torrents that want to raise. for torrent in toberaised: maxup = torrent.connection.maxrate[dir] newreservedrate = torrent.connection.rate[dir] + self.meancalcupth newmaxup = maxup + (newreservedrate - maxup) * realupfactor maxlocalup = float(torrent.connection.getLocalRate(dir)) if maxlocalup > 0 and newreservedrate > maxlocalup: newmaxup = maxup + (maxlocalup - maxup) * realupfactor torrent.connection.maxrate[dir] = newmaxup #print "index :", torrent.listindex, "; rate raised from", maxup, "to", torrent.connection.maxrate[dir] ################################################ # Set new max rate to all active torrents ################################################ for torrent in toberegulated: torrent.connection.setRate(torrent.connection.maxrate[dir], dir) return ########################################################################### #print "PHASE 2" ########################################################################### # -a- Each torrent that wants its rate to be raised or not to be changed will have its reserved rate lowered # to compensate the bandwidth given in priority to torrents with rate below 3 kB/s and torrents with local rate # settings if "prioritize local" is set. This lowering must not bring the reserved rate of a torrent below 3 kB/s. # Torrents will be sorted by their reserved rate and treated from the lower to the bigger. If a part of the lowering # cannot be achieved with a torrent,it will be dispatched to the pool of the remaining torrents to be treated. # After this, there may still be more total rate reserved than available rate because of the min 3 kB/s rule. ########################################################################### # -a- if availableratetobedistributed < 0: rate_id = [] pooltobelowered = toberaised + nottobechanged rate_id = [torrent for torrent in pooltobelowered if torrent.connection.rate[dir] > self.rateminimum[dir]] sizerate_id = len(rate_id) # Sort by increasing reserved rate rate_id.sort(key = lambda x: x.connection.maxrate[dir]) if rate_id: ratenotassignedforeach = availableratetobedistributed / sizerate_id # Compute new reserved rate i = 0 for torrent in rate_id: # (availableratetobedistributed and ratenotassignedforeach are negative numbers) newmaxrate = torrent.connection.maxrate[dir] + ratenotassignedforeach i += 1 if newmaxrate < self.rateminimum[dir]: # if some rate lowering could not be dispatched, it will be distributed to the next torrents # in the list (which are higher in max rate because the list is sorted this way) if i != sizerate_id: ratenotassignedforeach += (newmaxrate - self.rateminimum[dir]) / (sizerate_id - i) newmaxrate = self.rateminimum[dir] torrent.connection.maxrate[dir] = newmaxrate # print "%i lowered from %.3f to %.3f" % (t[1].listindex, t[0], newmaxrate) #print "availableratetobedistributed is now %.3f" % availableratetobedistributed ########################################################################### #print "PHASE 2 algo with mean rate" ########################################################################### # Phase 2 : There's no more available bandwidth to be distributed, I split the total max between active torrents. # -b- Compute the mean max rate for the pool of torrents that want their rate to be raised or not to be changed # and list torrents below and above that mean value. # -c- The regulation for torrents that want to have their rate raised is computed this way : # The idea is to target a mean rate for all torrents that want to raise their rate or don't want to have it # changed, taking into account the max rates of local settings, and the fact that no torrent must be lowered down below # 3 kB/s. # To sum up : In Phase 2, the reserved rate is leading the real rate . # -b- # Mean reserved rate calculation # If prioritizelocal is set, all torrents with a local rate settting are completely excluded from # the bandwidth exchange phase between other torrents. This is because this phase # targets a mean rate between torrents that want to upload more, and when prioritizelocal # is set, torrents with a local rate settting can be very far from this mean rate and their # own purpose is not to integrate the pool of other torrents but to live their own life (!) if toberaised or nottobechanged: meanrate /= len(toberaised) + len(nottobechanged) #print "Mean rate over 3 kB/s : %.1f" % meanrate raisedbelowm = [] # ids for torrents to be raised and with reserved rate below mean max rate allabovem = [] # ids for torrents to be raised or not to be changed and with reserved rate above mean max rate for torrent in toberaised: if torrent.connection.maxrate[dir] > meanrate: allabovem.append(torrent) elif torrent.connection.maxrate[dir] < meanrate: raisedbelowm.append(torrent) for torrent in nottobechanged: if torrent.connection.maxrate[dir] > meanrate: allabovem.append(torrent) # -c- if raisedbelowm and allabovem: # Available bandwidth exchange : up = 0.0 down = 0.0 for torrent in raisedbelowm: toadd = meanrate - torrent.connection.maxrate[dir] maxlocalrate_float = float(torrent.connection.getLocalRate(dir)) if maxlocalrate_float > 0 and maxlocalrate_float <= meanrate: toadd = maxlocalrate_float - torrent.connection.maxrate[dir] up += toadd for torrent in allabovem: down += torrent.connection.maxrate[dir] - meanrate if up > down: limitup = down / up # Speed up slow torrents that want their rate to be raised : # Each one must have its reserved rate raised slowly enough to let it follow this raise if it really # wants to get higher. If we set the reserved to the max in one shot, these torrents will be then detected # in the next phase 1 as to be lowered, which is not what we want. realup = 0.0 for torrent in raisedbelowm: maxup = torrent.connection.maxrate[dir] toadd = meanrate - maxup maxlocalrate_float = float(torrent.connection.getLocalRate(dir)) if maxlocalrate_float > 0 and maxlocalrate_float <= meanrate: toadd = maxlocalrate_float - maxup if up > down: toadd *= limitup # step is computed such as if the torrent keeps on raising at the same rate as before, it will be # analysed as still wanting to raise by the next phase 1 check step = 2 * (torrent.connection.rate[dir] + self.calcupth2 - maxup) if toadd < step: torrent.connection.maxrate[dir] = maxup + toadd realup += toadd else: torrent.connection.maxrate[dir] = maxup + step realup += step #print "index :", torrent.listindex, "; rate raised from", maxup, "to", torrent.connection.maxrate[dir] realup /= len(allabovem) # Slow down fast torrents : for torrent in allabovem: maxup = torrent.connection.maxrate[dir] torrent.connection.maxrate[dir] = maxup - realup #print "index :", torrent.listindex, "; rate lowered from", maxup, "to", torrent.listindex ################################################ # Set new max rate to all active torrents ################################################ for torrent in toberegulated: torrent.connection.setRate(torrent.connection.maxrate[dir], dir)
def CalculateBandwidth(self, dir="up"): if dir == "up": workingset = union(self.utility.torrents["downloading"], self.utility.torrents["seeding"]) else: workingset = self.utility.torrents["downloading"] # Limit working set to active torrents with connections: workingset = [ torrent for torrent in workingset if torrent.status.isActive() and torrent.connection.engine.hasConnections ] # No active file, not need to calculate if not workingset: return maxrate = self.MaxRate(dir) # See if global rate settings are set to unlimited if maxrate == 0: # Unlimited rate for torrent in workingset: torrent.connection.maxrate[ dir] = torrent.connection.getLocalRate(dir) torrent.connection.setRate(torrent.connection.maxrate[dir], dir) return #print "====================== BEGINNING ALGO ======= th1=%.1f ; th2=%.1f =============================" % (self.calcupth1, self.calcupth2) ####################################################### # - Find number of completed/incomplete torrent # - Number of torrent using local setting # - bandwidth already used by torrents # - Sorting of torrents in lists according to their will in matter of upload rate : # (tobelowered, toberaisedinpriority, toberaised, nottobechanged) ####################################################### # Option set in Preferences/Queue. # If not set, torrents with rate local settings are treated like other torrents, except they have their # own max rate they can't cross over. The consequence is a behaviour slightly different from the behavior of # ABC releases prior to 2.7.0. # If set, this gives the algorithm the behaviour of ABC releases prior to 2.7.0 : the torrents with an rate # local setting will be granted bandwidth in priority to fulfill their local setting, even is this one # is higher than the global max rate setting, and even if this bandwidth must be taken from other active # torrents wihout a local rate setting. These torrents will not take part in the rate exchange # between active torrents when all bandwidth has been distributed, since they will have been served in priority. prioritizelocal = self.utility.config.Read('prioritizelocal', "boolean") # torrents with local rate settings when prioritizelocal is set (see prioritizelocal) localprioactive = [] # torrents for which measured rate is lowering and so reserved rate can be lowered tobelowered = [] # torrents for which measured rate is growing and so reserved rate can be raised, # (with reserved rate > 3 kB/s for uploading) toberaised = [] # torrents for which reserved rate can be raised, with reserved rate < 3 kB/s # These will always be raised even there's no available up bandwith, to fulfill the min 3 kB/s rate rule toberaisedinpriority = [] # torrents for which reserved rate is not to be changed and is > rateminimum; (for these, the # measured rate is between (max upload reserved - calcupth1) and (max upload reserved - calcupth2) nottobechanged = [] meanrate = 0.0 # mean max rate for torrents to be raised or not to be changed ; it will be used to decide which torrents # must be raised amongst those that want to get higher and that must share the available up bandwidth. The torrents # that don't want to change their rate and that are below 3 kB/s are not taken into account on purpose, because # these ones will never be lowered to give more rate to a torrent that wants to raise its rate, or to # compensate for the rate given to torrents to be raised in priority. for torrent in workingset: # Active Torrent currentrate = torrent.connection.rate[dir] maxrate_float = torrent.connection.maxrate[dir] # Torrents dispatch if prioritizelocal and torrent.connection.getLocalRate(dir, True): localprioactive.append(torrent) elif currentrate < 0.05: # These are the torrents that don't want to have their rate changed and that have an allmost null rate # They will not go lower, we can reset their reserved rate until they want to get higher torrent.connection.maxrate[dir] = 0.0 elif maxrate_float - currentrate > self.calcupth1: tobelowered.append(torrent) elif maxrate_float - currentrate <= self.calcupth2: if currentrate < self.rateminimum[dir]: toberaisedinpriority.append(torrent) else: toberaised.append(torrent) meanrate += maxrate_float elif currentrate > self.rateminimum[dir]: nottobechanged.append(torrent) meanrate += maxrate_float # print "index: %i ; rate: %.1f ; reserved: %.1f ; maxlocal: %.1f" % (torrent.listindex, \ # currentrate, maxrate_float, float(torrent.connection.maxlocalrate[dir])) ############################################### # Calculate rate for each torrent ############################################### availableratetobedistributed = maxrate if ((availableratetobedistributed != 0) and (1 - (self.queue.totals_kb[dir] / availableratetobedistributed) > 0.20)): #print "FREE WHEELING TORRENTS" # If there's still at least 20% of available bandwidth, let the torrents do want they want # Keep a reserved max rate updated not to have to reinitilize it when we'll switch later # from free wheeling to controlled status. # Give BitTornado the highest possible value for max rate to speed up the rate rising for torrent in workingset: newrate = torrent.connection.rate[dir] + self.meancalcupth maxlocalrate = float(torrent.connection.getLocalRate(dir)) if maxlocalrate > 0: rateToUse = maxlocalrate if newrate > maxlocalrate: newrate = maxlocalrate else: rateToUse = self.MaxRate(dir) torrent.connection.maxrate[dir] = newrate # Send to BitTornado torrent.connection.setRate(rateToUse, dir) return ########################################################################### # First treat special torrents before going on sharing and distributing ########################################################################### # Treat in priority the torrents with rate below 3 kB/s and that want to get a higher rate grantedfortoberaisedinpriority = 0.0 for torrent in toberaisedinpriority: newreservedrate = torrent.connection.rate[dir] + self.meancalcupth if newreservedrate > self.rateminimum[dir]: grantedfortoberaisedinpriority += self.rateminimum[ dir] - torrent.connection.maxrate[dir] torrent.connection.maxrate[dir] = self.rateminimum[dir] else: grantedfortoberaisedinpriority += newreservedrate - torrent.connection.maxrate[ dir] torrent.connection.maxrate[dir] = newreservedrate # Treat in priority the torrents with a local rate setting if "prioritize local" is set # As with the free wheeling torrents, keep on tracking the real value of rate while giving BitTornado # the highest max rate to speed up the rate rising. grantedforlocaltoberaised = 0.0 for torrent in localprioactive: newrate = torrent.connection.rate[dir] + self.meancalcupth maxlocalrate = float(torrent.connection.getLocalRate(dir)) if newrate > maxlocalrate: newrate = maxlocalrate grantedforlocaltoberaised += newrate - torrent.connection.maxrate[ dir] torrent.connection.maxrate[dir] = newrate # Send to BitTornado torrent.connection.setRate(maxlocalrate, dir) # Torrents that want to be lowered in rate (and give back some reserved bandwidth) givenbackbytobelowered = 0.0 for torrent in tobelowered: newreservedrate = torrent.connection.rate[dir] + self.meancalcupth givenbackbytobelowered += newreservedrate - torrent.connection.maxrate[ dir] torrent.connection.maxrate[dir] = newreservedrate # Add to available rate to be distributed the rate given back by the torrents that have been lowered ; # Substract from available rate the rate used for each torrent that have been be raised in priority (torrents with rate # below 3 kB/s and that want to get higher). availableratetobedistributed += givenbackbytobelowered - grantedfortoberaisedinpriority - grantedforlocaltoberaised - self.queue.totals_kb[ dir] #print "availableratetobedistributed is %.3f" % availableratetobedistributed # localprioactive torrents have already been updated if prioritizelocal is set toberegulated = [ torrent for torrent in workingset if torrent not in localprioactive ] # There's nothing to do if no torrent want to be raised if not toberaised: ################################################ # Set new max rate to all active torrents ################################################ for torrent in toberegulated: torrent.connection.setRate(torrent.connection.maxrate[dir], dir) return if availableratetobedistributed > 0: ########################################################################### #print "PHASE 1" ########################################################################### # Phase 1 : As long as there's available bandwidth below the total max to be distributed, I give some # to any torrents that asks for it. # There's a special case with torrents to be raised that have a local max rate : they must be topped to their max local # rate and the surplus part of the reserved bandwidth may be reused. # To sum up : In Phase 1, the measured rate is leading the reserved rate. # Check if all torrents that claim a higher reserved rate will be satisfied claimedrate = 0.0 for torrent in toberaised: maxup = torrent.connection.maxrate[dir] newreservedrate = torrent.connection.rate[ dir] + self.meancalcupth toadd = newreservedrate maxlocalup = float(torrent.connection.getLocalRate(dir)) if maxlocalup > 0 and newreservedrate > maxlocalup: toadd = maxlocalup claimedrate += toadd - maxup #print "Claimed rate :", claimedrate #print "Available rate :", availableratetobedistributed if claimedrate <= availableratetobedistributed: realupfactor = 1 else: realupfactor = availableratetobedistributed / claimedrate # If all claims can be fulfilled ; we distribute and go to end. # If there's not enough remaining rate to fulfill all claims, the remaining available rate will be # distributed proportionally between all torrents that want to raise. for torrent in toberaised: maxup = torrent.connection.maxrate[dir] newreservedrate = torrent.connection.rate[ dir] + self.meancalcupth newmaxup = maxup + (newreservedrate - maxup) * realupfactor maxlocalup = float(torrent.connection.getLocalRate(dir)) if maxlocalup > 0 and newreservedrate > maxlocalup: newmaxup = maxup + (maxlocalup - maxup) * realupfactor torrent.connection.maxrate[dir] = newmaxup #print "index :", torrent.listindex, "; rate raised from", maxup, "to", torrent.connection.maxrate[dir] ################################################ # Set new max rate to all active torrents ################################################ for torrent in toberegulated: torrent.connection.setRate(torrent.connection.maxrate[dir], dir) return ########################################################################### #print "PHASE 2" ########################################################################### # -a- Each torrent that wants its rate to be raised or not to be changed will have its reserved rate lowered # to compensate the bandwidth given in priority to torrents with rate below 3 kB/s and torrents with local rate # settings if "prioritize local" is set. This lowering must not bring the reserved rate of a torrent below 3 kB/s. # Torrents will be sorted by their reserved rate and treated from the lower to the bigger. If a part of the lowering # cannot be achieved with a torrent,it will be dispatched to the pool of the remaining torrents to be treated. # After this, there may still be more total rate reserved than available rate because of the min 3 kB/s rule. ########################################################################### # -a- if availableratetobedistributed < 0: rate_id = [] pooltobelowered = toberaised + nottobechanged rate_id = [ torrent for torrent in pooltobelowered if torrent.connection.rate[dir] > self.rateminimum[dir] ] sizerate_id = len(rate_id) # Sort by increasing reserved rate rate_id.sort(key=lambda x: x.connection.maxrate[dir]) if rate_id: ratenotassignedforeach = availableratetobedistributed / sizerate_id # Compute new reserved rate i = 0 for torrent in rate_id: # (availableratetobedistributed and ratenotassignedforeach are negative numbers) newmaxrate = torrent.connection.maxrate[ dir] + ratenotassignedforeach i += 1 if newmaxrate < self.rateminimum[dir]: # if some rate lowering could not be dispatched, it will be distributed to the next torrents # in the list (which are higher in max rate because the list is sorted this way) if i != sizerate_id: ratenotassignedforeach += (newmaxrate - self.rateminimum[dir]) / ( sizerate_id - i) newmaxrate = self.rateminimum[dir] torrent.connection.maxrate[dir] = newmaxrate # print "%i lowered from %.3f to %.3f" % (t[1].listindex, t[0], newmaxrate) #print "availableratetobedistributed is now %.3f" % availableratetobedistributed ########################################################################### #print "PHASE 2 algo with mean rate" ########################################################################### # Phase 2 : There's no more available bandwidth to be distributed, I split the total max between active torrents. # -b- Compute the mean max rate for the pool of torrents that want their rate to be raised or not to be changed # and list torrents below and above that mean value. # -c- The regulation for torrents that want to have their rate raised is computed this way : # The idea is to target a mean rate for all torrents that want to raise their rate or don't want to have it # changed, taking into account the max rates of local settings, and the fact that no torrent must be lowered down below # 3 kB/s. # To sum up : In Phase 2, the reserved rate is leading the real rate . # -b- # Mean reserved rate calculation # If prioritizelocal is set, all torrents with a local rate settting are completely excluded from # the bandwidth exchange phase between other torrents. This is because this phase # targets a mean rate between torrents that want to upload more, and when prioritizelocal # is set, torrents with a local rate settting can be very far from this mean rate and their # own purpose is not to integrate the pool of other torrents but to live their own life (!) if toberaised or nottobechanged: meanrate /= len(toberaised) + len(nottobechanged) #print "Mean rate over 3 kB/s : %.1f" % meanrate raisedbelowm = [ ] # ids for torrents to be raised and with reserved rate below mean max rate allabovem = [ ] # ids for torrents to be raised or not to be changed and with reserved rate above mean max rate for torrent in toberaised: if torrent.connection.maxrate[dir] > meanrate: allabovem.append(torrent) elif torrent.connection.maxrate[dir] < meanrate: raisedbelowm.append(torrent) for torrent in nottobechanged: if torrent.connection.maxrate[dir] > meanrate: allabovem.append(torrent) # -c- if raisedbelowm and allabovem: # Available bandwidth exchange : up = 0.0 down = 0.0 for torrent in raisedbelowm: toadd = meanrate - torrent.connection.maxrate[dir] maxlocalrate_float = float( torrent.connection.getLocalRate(dir)) if maxlocalrate_float > 0 and maxlocalrate_float <= meanrate: toadd = maxlocalrate_float - torrent.connection.maxrate[dir] up += toadd for torrent in allabovem: down += torrent.connection.maxrate[dir] - meanrate if up > down: limitup = down / up # Speed up slow torrents that want their rate to be raised : # Each one must have its reserved rate raised slowly enough to let it follow this raise if it really # wants to get higher. If we set the reserved to the max in one shot, these torrents will be then detected # in the next phase 1 as to be lowered, which is not what we want. realup = 0.0 for torrent in raisedbelowm: maxup = torrent.connection.maxrate[dir] toadd = meanrate - maxup maxlocalrate_float = float( torrent.connection.getLocalRate(dir)) if maxlocalrate_float > 0 and maxlocalrate_float <= meanrate: toadd = maxlocalrate_float - maxup if up > down: toadd *= limitup # step is computed such as if the torrent keeps on raising at the same rate as before, it will be # analysed as still wanting to raise by the next phase 1 check step = 2 * (torrent.connection.rate[dir] + self.calcupth2 - maxup) if toadd < step: torrent.connection.maxrate[dir] = maxup + toadd realup += toadd else: torrent.connection.maxrate[dir] = maxup + step realup += step #print "index :", torrent.listindex, "; rate raised from", maxup, "to", torrent.connection.maxrate[dir] realup /= len(allabovem) # Slow down fast torrents : for torrent in allabovem: maxup = torrent.connection.maxrate[dir] torrent.connection.maxrate[dir] = maxup - realup #print "index :", torrent.listindex, "; rate lowered from", maxup, "to", torrent.listindex ################################################ # Set new max rate to all active torrents ################################################ for torrent in toberegulated: torrent.connection.setRate(torrent.connection.maxrate[dir], dir)