FileDocCategorySizeDatePackage
DefaultRankCalculator.javaAPI DocAzureus 3.0.3.426803Tue Sep 04 11:13:08 BST 2007com.aelitis.azureus.plugins.startstoprules.defaultplugin

DefaultRankCalculator

public class DefaultRankCalculator extends Object implements Comparable
author
TuxPaper
created
Dec 13, 2005

Fields Summary
public static final int
FIRSTPRIORITY_ALL
All of the First Priority rules must match
public static final int
FIRSTPRIORITY_ANY
Any of the First Priority rules must match
private static final int
FORCE_ACTIVE_FOR
Force torrent to be "Actively Seeding/Downloading" for this many ms upon start of torrent.
private static final int
ACTIVE_CHANGE_WAIT
Wait XX ms before really changing activity (DL or CDing) state when state changes via speed change
private static int
SPRATIO_BASE_LIMIT
Maximium ranking that a torrent can get using the SPRATIO ranking type
private static int
SEEDONLY_SHIFT
Amount to shift over the rank of the SEEDONLY ranking type, to make room in case the user has fallback to SPRATIO set.
private static org.gudy.azureus2.core3.config.COConfigurationListener
configListener
For loading config settings
public static final int
SR_COMPLETE_STARTS_AT
Rank that complete starts at (and incomplete ends at + 1)
public static final int
SR_TIMED_QUEUED_ENDS_AT
Maximimum ranking for time queue mode. 1 unit is a second
public static final int
SR_IGNORED_LESS_THAN
Ranks below this value are for torrents to be ignored (moved to bottom & queued)
public static final int
SR_NOTQUEUED
Seeding Rank value when download is marked as not queued
public static final int
SR_FP_SPRATIOMET
Seeding Rank value when download is marked as S:P Ratio Met for FP
public static final int
SR_RATIOMET
Seeding Rank value when download is marked as P:1S Ratio Met
public static final int
SR_NUMSEEDSMET
Seeding Rank value when download is marked as # Seeds Met
public static final int
SR_FP0PEERS
Seeding Rank value when download is marked as 0 Peers and FP
public static final int
SR_0PEERS
Seeding Rank value when download is marked as 0 Peers
public static final int
SR_SHARERATIOMET
Seeding Rank value when download is marked as Share Ratio Met
protected static int
iRankType
Ranking System to use
private static int
minPeersToBoostNoSeeds
Min # of Peers needed before boosting the rank of downloads with no seeds
private static int
minSpeedForActiveDL
Min Speed needed to count a incomplete download as being actively downloading
private static int
minSpeedForActiveSeeding
Min speed needed to count a complete download as being actively seeding
private static int
iIgnoreSeedCount
private static boolean
bIgnore0Peers
private static int
iIgnoreShareRatio
private static int
iIgnoreShareRatio_SeedStart
private static int
iIgnoreRatioPeers
private static int
iIgnoreRatioPeers_SeedStart
private static int
iRankTypeSeedFallback
private static boolean
bPreferLargerSwarms
private static int
minQueueingShareRatio
private static int
iFirstPriorityIgnoreSPRatio
private static boolean
bFirstPriorityIgnore0Peer
private static int
iFirstPriorityType
private static int
iFirstPrioritySeedingMinutes
private static int
iFirstPriorityActiveMinutes
private static long
minTimeAlive
private static boolean
bAutoStart0Peers
protected org.gudy.azureus2.plugins.download.Download
dl
private boolean
bActivelyDownloading
private long
lDLActivelyChangedOn
private boolean
bActivelySeeding
private long
lCDActivelyChangedOn
private boolean
bIsFirstPriority
public String
sExplainFP
Public for tooltip to access it
public String
sExplainSR
Public for tooltip to access it
public String
sTrace
Public for tooltip to access it
private org.gudy.azureus2.core3.util.AEMonitor
downloadData_this_mon
private final StartStopRulesDefaultPlugin
rules
int
lastModifiedScrapeResultPeers
int
lastModifiedScrapeResultSeeds
int
lastModifiedShareRatio
boolean
lastScrapeResultOk
Constructors Summary
public DefaultRankCalculator(StartStopRulesDefaultPlugin _rules, org.gudy.azureus2.plugins.download.Download _dl)
Default Initializer

param
_rules
param
_dl


	       	 
	     
		rules = _rules;
		dl = _dl;

		try {
			downloadData_this_mon.enter();

			if (configListener == null) {

				configListener = new COConfigurationListener() {
					public void configurationSaved() {
						reloadConfigParams(rules.plugin_config);
					}
				};

				COConfigurationManager.addListener(configListener);
				configListener.configurationSaved();
			}
		} finally {
			downloadData_this_mon.exit();
		}
	
Methods Summary
public booleanchangeChecker()
Check Seeders for various changes not triggered by listeners

return
True: something changed

		if (getActivelySeeding()) {
			int shareRatio = dl.getStats().getShareRatio();
			int numSeeds = rules.calcSeedsNoUs(dl);

			if (iIgnoreShareRatio != 0 && shareRatio >= iIgnoreShareRatio
					&& (numSeeds >= iIgnoreShareRatio_SeedStart || !lastScrapeResultOk)
					&& shareRatio != -1) {
				return true;
			}
		}

		/* READY downloads are usually waiting for a seeding torrent to
		 stop (the seeding torrent probably is within the "Minimum Seeding
		 Time" setting)
		 
		 The rules may go through several cycles before a READY torrent is
		 processed
		 */
		if (dl.getState() == Download.ST_READY) {
			if (rules.bDebugLog)
				rules.log.log(dl.getTorrent(), LoggerChannel.LT_INFORMATION,
						"somethingChanged: Download is ready");
			return true;
		}

		return false;
	
public intcompareTo(java.lang.Object obj)
Sort first by SeedingRank Descending, then by Position Ascending.

		if (!(obj instanceof DefaultRankCalculator)) {
			return -1;
		}

		DefaultRankCalculator dlData = (DefaultRankCalculator) obj;
		// Test Completeness
		boolean aIsComplete = dlData.dl.isComplete();
		boolean bIsComplete = dl.isComplete();
		if (aIsComplete && !bIsComplete)
			return 1;
		if (!aIsComplete && bIsComplete)
			return -1;

		// Test FP
		if (dlData.bIsFirstPriority && !bIsFirstPriority)
			return 1;
		if (!dlData.bIsFirstPriority && bIsFirstPriority)
			return -1;

		if (iRankType == StartStopRulesDefaultPlugin.RANK_NONE) {
			return dl.getPosition() - dlData.dl.getPosition();
		}

		// Check Rank
		int value = dlData.dl.getSeedingRank() - dl.getSeedingRank();
		if (value != 0)
			return value;

		if (iRankType != StartStopRulesDefaultPlugin.RANK_TIMED) {
			// Test Large/Small Swarm pref
			int numPeersThem = dlData.lastModifiedScrapeResultPeers;
			int numPeersUs = lastModifiedScrapeResultPeers;
			if (bPreferLargerSwarms)
				value = numPeersThem - numPeersUs;
			else
				value = numPeersUs - numPeersThem;
			if (value != 0)
				return value;

			// Test Share Ratio
			value = lastModifiedShareRatio - dlData.lastModifiedShareRatio;
			if (value != 0)
				return value;
		}

		// Test Position
		return dl.getPosition() - dlData.dl.getPosition();
	
public booleangetActivelyDownloading()
Retrieves whether the torrent is "actively" downloading

return
true: actively downloading

		boolean bIsActive = false;
		DownloadStats stats = dl.getStats();
		int state = dl.getState();

		// In order to be active,
		// - Must be downloading (and thus incomplete)
		// - Must be above speed threshold, or started less than 30s ago
		if (state != Download.ST_DOWNLOADING) {
			bIsActive = false;
		} else if (SystemTime.getCurrentTime() - stats.getTimeStarted() <= FORCE_ACTIVE_FOR) {
			bIsActive = true;
		} else {
			// activity based on DL Average
			bIsActive = (stats.getDownloadAverage() >= minSpeedForActiveDL);

			if (bActivelyDownloading != bIsActive) {
				long now = SystemTime.getCurrentTime();
				// Change
				if (lDLActivelyChangedOn == -1) {
					// Start Timer
					lDLActivelyChangedOn = now;
					bIsActive = !bIsActive;
				} else if (now - lDLActivelyChangedOn < ACTIVE_CHANGE_WAIT) {
					// Continue as old state until timer finishes
					bIsActive = !bIsActive;
				}
			} else {
				// no change, reset timer
				lDLActivelyChangedOn = -1;
			}
		}

		if (bActivelyDownloading != bIsActive) {
			bActivelyDownloading = bIsActive;
			if (rules != null) {
				rules.requestProcessCycle(null);
				if (rules.bDebugLog)
					rules.log.log(dl.getTorrent(), LoggerChannel.LT_INFORMATION,
							"somethingChanged: ActivelyDownloading changed");
			}
		}
		return bActivelyDownloading;
	
public booleangetActivelySeeding()
Retrieves whether the torrent is "actively" seeding

return
true: actively seeding

		boolean bIsActive = false;
		DownloadStats stats = dl.getStats();
		int state = dl.getState();
		// Timed torrents don't use a speed threshold, since they are based on time!
		// However, First Priorities need to be checked for activity so that 
		// timed ones can start when FPs are below threshold.  Ditto for 0 Peers
		// when bAutoStart0Peers
		if (iRankType == StartStopRulesDefaultPlugin.RANK_TIMED
				&& !isFirstPriority()
				&& !(bAutoStart0Peers && rules.calcPeersNoUs(dl) == 0 && lastScrapeResultOk)) {
			bIsActive = (state == Download.ST_SEEDING);

		} else if (state != Download.ST_SEEDING
				|| (bAutoStart0Peers && rules.calcPeersNoUs(dl) == 0)) {
			// Not active if we aren't seeding
			// Not active if we are AutoStarting 0 Peers, and peer count == 0
			bIsActive = false;
		} else if (SystemTime.getCurrentTime() - stats.getTimeStarted() <= FORCE_ACTIVE_FOR) {
			bIsActive = true;
		} else {
			bIsActive = (stats.getUploadAverage() >= minSpeedForActiveSeeding);

			if (bActivelySeeding != bIsActive) {
				long now = SystemTime.getCurrentTime();
				// Change
				if (lCDActivelyChangedOn == -1) {
					// Start Timer
					lCDActivelyChangedOn = now;
					bIsActive = !bIsActive;
				} else if (now - lCDActivelyChangedOn < ACTIVE_CHANGE_WAIT) {
					// Continue as old state until timer finishes
					bIsActive = !bIsActive;
				}
			} else {
				// no change, reset timer
				lCDActivelyChangedOn = -1;
			}
		}

		if (bActivelySeeding != bIsActive) {
			bActivelySeeding = bIsActive;
			if (rules != null) {
				rules.requestProcessCycle(null);
				if (rules.bDebugLog)
					rules.log.log(dl.getTorrent(), LoggerChannel.LT_INFORMATION,
							"somethingChanged: ActivelySeeding changed");
			}
		}
		return bActivelySeeding;
	
public booleangetCachedIsFP()

return
last calculated FP state

		return bIsFirstPriority;
	
public org.gudy.azureus2.plugins.download.DownloadgetDownloadObject()

		return dl;
	
public booleanisFirstPriority()
Does the torrent match First Priority criteria?

return
FP State

		boolean bFP = pisFirstPriority();

		if (bIsFirstPriority != bFP) {
			bIsFirstPriority = bFP;
			rules.requestProcessCycle(null);
			if (rules.bDebugLog)
				rules.log.log(dl.getTorrent(), LoggerChannel.LT_INFORMATION,
						"somethingChanged: FP changed");
		}
		return bIsFirstPriority;
	
public booleanisForceActive()

		DownloadStats stats = dl.getStats();
		return SystemTime.getCurrentTime() - stats.getTimeStarted() <= FORCE_ACTIVE_FOR;
	
private booleanpisFirstPriority()

		if (rules.bDebugLog)
			sExplainFP = "FP if "
					+ (iFirstPriorityType == FIRSTPRIORITY_ALL ? "all" : "any")
					+ " criteria match:\n";

		if (!dl.isPersistent()) {
			if (rules.bDebugLog)
				sExplainFP += "Not FP: Download not persistent\n";
			return false;
		}

		if (dl.getState() == Download.ST_ERROR
				|| dl.getState() == Download.ST_STOPPED) {
			if (rules.bDebugLog)
				sExplainFP += "Not FP: Download is ERROR or STOPPED\n";
			return false;
		}

		// FP only applies to completed
		if (!dl.isComplete()) {
			if (rules.bDebugLog)
				sExplainFP += "Not FP: Download not complete\n";
			return false;
		}
		
		List listeners = rules.getFPListeners();
		for (Iterator iter = listeners.iterator(); iter.hasNext();) {
			StartStopRulesFPListener l = (StartStopRulesFPListener) iter.next();
			if (l.isFirstPriority(dl, lastModifiedScrapeResultSeeds, lastModifiedScrapeResultPeers)) {
				return true;
			}
		}

		// FP doesn't apply when S:P >= set SPratio (SPratio = 0 means ignore)
		if (lastModifiedScrapeResultPeers > 0 && lastModifiedScrapeResultSeeds > 0
				&& (lastModifiedScrapeResultSeeds / lastModifiedScrapeResultPeers) >= iFirstPriorityIgnoreSPRatio
				&& iFirstPriorityIgnoreSPRatio != 0) {
			if (rules.bDebugLog)
				sExplainFP += "Not FP: S:P >= " + iFirstPriorityIgnoreSPRatio + ":1\n";
			return false;
		}

		//not FP if no peers  //Nolar, 2105 - Gouss, 2203
		if (lastModifiedScrapeResultPeers == 0 && lastScrapeResultOk && bFirstPriorityIgnore0Peer) {
			if (rules.bDebugLog)
				sExplainFP += "Not FP: 0 peers\n";
			return false;
		}

		int shareRatio = dl.getStats().getShareRatio();
		boolean bLastMatched = (shareRatio != -1)
				&& (shareRatio < minQueueingShareRatio);

		if (rules.bDebugLog)
			sExplainFP += "  shareRatio(" + shareRatio + ") < "
					+ minQueueingShareRatio + "=" + bLastMatched + "\n";

		if (!bLastMatched && iFirstPriorityType == FIRSTPRIORITY_ALL) {
			if (rules.bDebugLog)
				sExplainFP += "..Not FP.  Exit Early\n";
			return false;
		}
		if (bLastMatched && iFirstPriorityType == FIRSTPRIORITY_ANY) {
			if (rules.bDebugLog)
				sExplainFP += "..Is FP.  Exit Early\n";
			return true;
		}

		bLastMatched = (iFirstPrioritySeedingMinutes == 0);
		if (!bLastMatched) {
			long timeSeeding = dl.getStats().getSecondsOnlySeeding();
			if (timeSeeding >= 0) {
				bLastMatched = (timeSeeding < (iFirstPrioritySeedingMinutes * 60));
				if (rules.bDebugLog)
					sExplainFP += "  SeedingTime(" + timeSeeding + ") < "
							+ (iFirstPrioritySeedingMinutes * 60) + "=" + bLastMatched + "\n";
				if (!bLastMatched && iFirstPriorityType == FIRSTPRIORITY_ALL) {
					if (rules.bDebugLog)
						sExplainFP += "..Not FP.  Exit Early\n";
					return false;
				}
				if (bLastMatched && iFirstPriorityType == FIRSTPRIORITY_ANY) {
					if (rules.bDebugLog)
						sExplainFP += "..Is FP.  Exit Early\n";
					return true;
				}
			}
		} else if (rules.bDebugLog) {
			sExplainFP += "  Skipping Seeding Time check (user disabled)\n";
		}

		bLastMatched = (iFirstPriorityActiveMinutes == 0);
		if (!bLastMatched) {
			long timeActive = dl.getStats().getSecondsDownloading()
					+ dl.getStats().getSecondsOnlySeeding();
			if (timeActive >= 0) {
				bLastMatched = (timeActive < (iFirstPriorityActiveMinutes * 60));
				if (rules.bDebugLog)
					sExplainFP += "  ActiveTime(" + timeActive + ") < "
							+ (iFirstPriorityActiveMinutes * 60) + "=" + bLastMatched + "\n";
				if (!bLastMatched && iFirstPriorityType == FIRSTPRIORITY_ALL) {
					if (rules.bDebugLog)
						sExplainFP += "..Not FP.  Exit Early\n";
					return false;
				}
				if (bLastMatched && iFirstPriorityType == FIRSTPRIORITY_ANY) {
					if (rules.bDebugLog)
						sExplainFP += "..Is FP.  Exit Early\n";
					return true;
				}
			}
		} else if (rules.bDebugLog) {
			sExplainFP += "  Skipping DL Time check (user disabled)\n";
		}

		if (iFirstPriorityType == FIRSTPRIORITY_ALL) {
			if (rules.bDebugLog)
				sExplainFP += "..Is FP\n";
			return true;
		}

		if (rules.bDebugLog)
			sExplainFP += "..Not FP\n";
		return false;
	
public intrecalcSeedingRank()
Assign Seeding Rank based on RankType

return
New Seeding Rank Value

		try {
			downloadData_this_mon.enter();

			sExplainSR = "";

			int oldSR = dl.getSeedingRank();
			DownloadStats stats = dl.getStats();

			int newSR = 0;

			// make undownloaded sort to top so they can start first.
			if (!dl.isComplete()) {
				newSR = SR_COMPLETE_STARTS_AT + (10000 - dl.getPosition());
				dl.setSeedingRank(newSR);
				if ( rules.bDebugLog ){
					sExplainSR += "  not complete. SetSR " + newSR + "\n";
				}
				return newSR;
			}

			// here we are seeding

			lastModifiedShareRatio = stats.getShareRatio();
			lastModifiedScrapeResultPeers = rules.calcPeersNoUs(dl);
			lastModifiedScrapeResultSeeds = rules.calcSeedsNoUs(dl);

			boolean bScrapeResultsOk = (lastModifiedScrapeResultPeers > 0 || lastModifiedScrapeResultSeeds > 0
					|| lastScrapeResultOk) && (lastModifiedScrapeResultPeers >= 0 && lastModifiedScrapeResultSeeds >= 0);

			if (!isFirstPriority()) {
				// Check Ignore Rules
				// never apply ignore rules to First Priority Matches
				// (we don't want leechers circumventing the 0.5 rule)

				//0 means unlimited
				if (iIgnoreShareRatio != 0 && lastModifiedShareRatio >= iIgnoreShareRatio
						&& (lastModifiedScrapeResultSeeds >= iIgnoreShareRatio_SeedStart || !lastScrapeResultOk)
						&& lastModifiedShareRatio != -1) {
					
					if (rules.bDebugLog)
						sExplainSR += "  shareratio met: shareRatio(" + lastModifiedShareRatio
								+ ") >= " + iIgnoreShareRatio + "\n";

					dl.setSeedingRank(SR_SHARERATIOMET);
					return SR_SHARERATIOMET;
				} else if (rules.bDebugLog && iIgnoreShareRatio != 0
						&& lastModifiedShareRatio >= iIgnoreShareRatio) {
					sExplainSR += "  shareratio NOT met: ";
					if (lastModifiedScrapeResultSeeds >= iIgnoreShareRatio_SeedStart) 
						sExplainSR += lastModifiedScrapeResultSeeds + " below seed threshold of "
								+ iIgnoreShareRatio_SeedStart;
					sExplainSR += "\n";
				}

				if (lastModifiedScrapeResultPeers == 0 && bScrapeResultsOk) {
					// If both bIgnore0Peers and bFirstPriorityIgnore0Peer are on,
					// we won't know which one it is at this point.
					// We have to use the normal SR_0PEERS in case it isn't FP
					if (bIgnore0Peers) {
						if (rules.bDebugLog)
							sExplainSR += "  Ignore 0 Peers criteria met\n";

						dl.setSeedingRank(SR_0PEERS);
						return SR_0PEERS;
					}

//					if (bFirstPriorityIgnore0Peer) {
//						if (rules.bDebugLog)
//							sExplainSR += "  Ignore 0 Peers criteria for FP met\n";
//
//						dl.setSeedingRank(SR_FP0PEERS);
//						return SR_FP0PEERS;
//					}
				} else if (rules.bDebugLog && lastModifiedScrapeResultPeers == 0) {
					sExplainSR += "  0 Peer Ignore rule NOT applied: Scrape invalid\n";
				}

//				if (numPeers != 0 && iFirstPriorityIgnoreSPRatio != 0
//						&& numSeeds / numPeers >= iFirstPriorityIgnoreSPRatio) {
//					if (rules.bDebugLog)
//						sExplainSR += "  Ignore rule for S:P Ratio for FP met.  Current: ("
//								+ (numSeeds / numPeers)
//								+ ") >= Threshold("
//								+ iFirstPriorityIgnoreSPRatio + ")\n";
//
//					dl.setSeedingRank(SR_FP_SPRATIOMET);
//					return SR_FP_SPRATIOMET;
//				}

				//0 means disabled
				if ((iIgnoreSeedCount != 0) && (lastModifiedScrapeResultSeeds >= iIgnoreSeedCount)) {
					if (rules.bDebugLog)
						sExplainSR += "  SeedCount Ignore rule met.  numSeeds("
								+ lastModifiedScrapeResultSeeds + " >= iIgnoreSeedCount(" + iIgnoreSeedCount + ")\n"; 

					dl.setSeedingRank(SR_NUMSEEDSMET);
					return SR_NUMSEEDSMET;
				}

				// Ignore when P:S ratio met
				// (More Peers for each Seed than specified in Config)
				//0 means never stop
				if (iIgnoreRatioPeers != 0 && lastModifiedScrapeResultSeeds != 0) {
					float ratio = (float) lastModifiedScrapeResultPeers / lastModifiedScrapeResultSeeds;
					if (ratio <= iIgnoreRatioPeers
							&& lastModifiedScrapeResultSeeds >= iIgnoreRatioPeers_SeedStart) {

						if (rules.bDebugLog)
							sExplainSR += "  P:S Ignore rule met.  ratio(" + ratio
									+ " <= threshold(" + iIgnoreRatioPeers_SeedStart + ")\n";

						dl.setSeedingRank(SR_RATIOMET);
						return SR_RATIOMET;
					}
				}
			}

			// Never do anything with rank type of none
			if (iRankType == StartStopRulesDefaultPlugin.RANK_NONE) {
				if (rules.bDebugLog)
					sExplainSR += "  Ranking Type set to none.. blanking seeding rank\n";
				
				// everythink ok!
				dl.setSeedingRank(newSR);
				return newSR;
			}

			if (iRankType == StartStopRulesDefaultPlugin.RANK_TIMED) {
				if (bIsFirstPriority) {
					newSR += SR_TIMED_QUEUED_ENDS_AT + 1;
					dl.setSeedingRank(newSR);
					return newSR;
				}

				int state = dl.getState();
				if (state == Download.ST_STOPPING || state == Download.ST_STOPPED
						|| state == Download.ST_ERROR) {
					if (rules.bDebugLog)
						sExplainSR += "  Download stopping, stopped or in error\n";
					dl.setSeedingRank(SR_NOTQUEUED);
					return SR_NOTQUEUED;
				} else if (state == Download.ST_SEEDING || state == Download.ST_READY
						|| state == Download.ST_WAITING || state == Download.ST_PREPARING) {
					// force sort to top
					long lMsElapsed = 0;
					if (state == Download.ST_SEEDING && !dl.isForceStart())
						lMsElapsed = (SystemTime.getCurrentTime() - stats
								.getTimeStartedSeeding());

					if (lMsElapsed >= minTimeAlive) {
						dl.setSeedingRank(1);
						if (oldSR > SR_TIMED_QUEUED_ENDS_AT) {
							rules.requestProcessCycle(null);
							if (rules.bDebugLog)
								rules.log.log(dl.getTorrent(), LoggerChannel.LT_INFORMATION,
										"somethingChanged: TimeUp");
						}
					} else {
						newSR = SR_TIMED_QUEUED_ENDS_AT + 1 + (int) (lMsElapsed / 1000);
						dl.setSeedingRank(newSR);
						if (oldSR <= SR_TIMED_QUEUED_ENDS_AT) {
							rules.requestProcessCycle(null);
							if (rules.bDebugLog)
								rules.log.log(dl.getTorrent(), LoggerChannel.LT_INFORMATION,
										"somethingChanged: strange timer change");
						}
					}
					return newSR;
				} else {
					if (oldSR <= 0) {
						newSR = SR_TIMED_QUEUED_ENDS_AT - dl.getPosition();
						dl.setSeedingRank(newSR);
						rules.requestProcessCycle(null);
						if (rules.bDebugLog)
							rules.log.log(dl.getTorrent(), LoggerChannel.LT_INFORMATION,
									"somethingChanged: NotIgnored");
					}
					return newSR;
				}
			}

			/** 
			 * Add to SeedingRank based on Rank Type
			 */

			// SeedCount and SPRatio require Scrape Results..
			if (bScrapeResultsOk) {
				if ((iRankType == StartStopRulesDefaultPlugin.RANK_SEEDCOUNT)
						&& (iRankTypeSeedFallback == 0 || iRankTypeSeedFallback > lastModifiedScrapeResultSeeds)) {
					if (lastModifiedScrapeResultSeeds < 10000)
						newSR = 10000 - lastModifiedScrapeResultSeeds;
					else
						newSR = 1;
					// shift over to make way for fallback
					newSR *= SEEDONLY_SHIFT;

				} else { // iRankType == RANK_SPRATIO or we are falling back
					if (lastModifiedScrapeResultPeers != 0) {
						if (lastModifiedScrapeResultSeeds == 0) {
							if (lastModifiedScrapeResultPeers >= minPeersToBoostNoSeeds)
								newSR += SPRATIO_BASE_LIMIT;
						} else { // numSeeds != 0 && numPeers != 0
							float x = (float) lastModifiedScrapeResultSeeds / lastModifiedScrapeResultPeers;
							newSR += SPRATIO_BASE_LIMIT / ((x + 1) * (x + 1));
						}
					}
				}
			} else {
				if (rules.bDebugLog)
					sExplainSR += "  Can't calculate SR, no scrape results\n";
			}

			if (newSR < 0)
				newSR = 1;

			if (newSR != oldSR)
				dl.setSeedingRank(newSR);
			return newSR;
		} finally {

			downloadData_this_mon.exit();
		}
	
public static voidreloadConfigParams(org.gudy.azureus2.plugins.PluginConfig cfg)
Load config values into the static variables

param
cfg

		final String PREFIX = "StartStopManager_";

		iRankType = cfg.getIntParameter(PREFIX + "iRankType");

		minPeersToBoostNoSeeds = cfg.getIntParameter(PREFIX
				+ "iMinPeersToBoostNoSeeds");
		minSpeedForActiveDL = cfg.getIntParameter(PREFIX + "iMinSpeedForActiveDL");
		minSpeedForActiveSeeding = cfg.getIntParameter(PREFIX
				+ "iMinSpeedForActiveSeeding");

		iRankTypeSeedFallback = cfg.getIntParameter(PREFIX
				+ "iRankTypeSeedFallback");
		bPreferLargerSwarms = cfg.getBooleanParameter(PREFIX
				+ "bPreferLargerSwarms");
		minTimeAlive = cfg.getIntParameter(PREFIX + "iMinSeedingTime") * 1000;
		bAutoStart0Peers = cfg.getBooleanParameter(PREFIX + "bAutoStart0Peers");

		// Ignore torrent if seed count is at least..
		iIgnoreSeedCount = cfg.getIntParameter(PREFIX + "iIgnoreSeedCount");
		bIgnore0Peers = cfg.getBooleanParameter(PREFIX + "bIgnore0Peers");
		iIgnoreShareRatio = (int) (1000 * cfg.getFloatParameter("Stop Ratio"));
		iIgnoreShareRatio_SeedStart = cfg.getIntParameter(PREFIX
				+ "iIgnoreShareRatioSeedStart");
		iIgnoreRatioPeers = cfg.getIntParameter("Stop Peers Ratio", 0);
		iIgnoreRatioPeers_SeedStart = cfg.getIntParameter(PREFIX
				+ "iIgnoreRatioPeersSeedStart", 0);

		minQueueingShareRatio = cfg.getIntParameter(PREFIX
				+ "iFirstPriority_ShareRatio");
		iFirstPriorityType = cfg.getIntParameter(PREFIX + "iFirstPriority_Type");
		iFirstPrioritySeedingMinutes = cfg.getIntParameter(PREFIX
				+ "iFirstPriority_SeedingMinutes");
		iFirstPriorityActiveMinutes = cfg.getIntParameter(PREFIX
				+ "iFirstPriority_DLMinutes");
		// Ignore FP
		iFirstPriorityIgnoreSPRatio = cfg.getIntParameter(PREFIX
				+ "iFirstPriority_ignoreSPRatio");
		bFirstPriorityIgnore0Peer = cfg.getBooleanParameter(PREFIX
				+ "bFirstPriority_ignore0Peer");
	
public java.lang.StringtoString()

		return String.valueOf(dl.getSeedingRank());