📄 startstoprulesdefaultplugin.java
字号:
(state == Download.ST_READY || state == Download.ST_WAITING
|| state == Download.ST_PREPARING ||
// Forced Start torrents are pre-included in count
(state == Download.ST_SEEDING && bActivelySeeding && !download.isForceStart()))) {
vars.numWaitingOrSeeding++;
if (bDebugLog)
sDebugLine += "\n Torrent is waiting or seeding";
}
// Note: First Priority are sorted to the top,
// so they will always start first
// XXX Change to waiting if queued and we have an open slot
if (!okToQueue
&& (state == Download.ST_QUEUED)
&& (totals.maxActive == 0 || vars.numWaitingOrSeeding < totals.maxSeeders)
//&& (totals.maxActive == 0 || (activeSeedingCount + activeDLCount) < totals.maxActive) &&
&& (rank >= DefaultRankCalculator.SR_IGNORED_LESS_THAN)
&& !vars.higherCDtoStart) {
try {
if (bDebugLog)
sDebugLine += "\n restart: ok2Q=" + okToQueue
+ "; QUEUED && numWaitingOrSeeding( "
+ vars.numWaitingOrSeeding + ") < maxSeeders ("
+ totals.maxSeeders + ")";
download.restart(); // set to Waiting
okToQueue = false;
totals.waitingToSeed++;
vars.numWaitingOrSeeding++;
if (iRankType == RANK_TIMED)
dlData.recalcSeedingRank();
} catch (Exception ignore) {/*ignore*/
}
state = download.getState();
} else if (bDebugLog && state == Download.ST_QUEUED) {
sDebugLine += "\n NOT restarting:";
if (rank < DefaultRankCalculator.SR_IGNORED_LESS_THAN)
sDebugLine += " torrent is being ignored";
else if (vars.higherCDtoStart)
sDebugLine += " a torrent with a higher rank is queued or starting";
else {
if (okToQueue)
sDebugLine += " no starting of okToQueue'd;";
if (vars.numWaitingOrSeeding >= totals.maxSeeders)
sDebugLine += " at limit, numWaitingOrSeeding("
+ vars.numWaitingOrSeeding + ") >= maxSeeders("
+ totals.maxSeeders + ")";
}
}
boolean bForceStop = false;
// Start download if ready and slot is available
if (state == Download.ST_READY
&& totals.activelyCDing < totals.maxSeeders) {
if (rank >= DefaultRankCalculator.SR_IGNORED_LESS_THAN
|| download.isForceStart()) {
try {
if (bDebugLog)
sDebugLine += "\n start: READY && total activelyCDing("
+ totals.activelyCDing + ") < maxSeeders("
+ totals.maxSeeders + ")";
download.start();
okToQueue = false;
} catch (Exception ignore) {
/*ignore*/
}
state = download.getState();
totals.activelyCDing++;
bActivelySeeding = true;
vars.numWaitingOrSeeding++;
} else if (okToQueue) {
// In between switching from STATE_WAITING and STATE_READY,
// and ignore rule was met, so move it back to Queued
bForceStop = true;
}
}
// if there's more torrents waiting/seeding than our max, or if
// there's a higher ranked torrent queued, stop this one
if (okToQueue || bForceStop) {
boolean okToStop = bForceStop;
if (!okToStop) {
// break up the logic into variables to make more readable
boolean bOverLimit = vars.numWaitingOrSeeding > totals.maxSeeders
|| (vars.numWaitingOrSeeding >= totals.maxSeeders && vars.higherCDtoStart);
boolean bSeeding = state == Download.ST_SEEDING;
// not checking AND (at limit of seeders OR rank is set to ignore) AND
// (Actively Seeding OR StartingUp OR Seeding a non-active download)
okToStop = !download.isChecking()
&& (bOverLimit || rank < DefaultRankCalculator.SR_IGNORED_LESS_THAN)
&& (bActivelySeeding || !bSeeding || (!bActivelySeeding && bSeeding));
if (bDebugLog) {
if (okToStop) {
sDebugLine += "\n stopAndQueue: ";
if (bOverLimit) {
if (vars.higherCDtoStart)
sDebugLine += "higherQueued (it should be seeding instead of this one)";
else
sDebugLine += "over limit";
} else if (rank < DefaultRankCalculator.SR_IGNORED_LESS_THAN)
sDebugLine += "ignoreRule met";
sDebugLine += " && ";
if (bActivelySeeding)
sDebugLine += "activelySeeding";
else if (!bSeeding)
sDebugLine += "not SEEDING";
else if (!bActivelySeeding && bSeeding)
sDebugLine += "SEEDING, but not actively";
}
} else {
sDebugLine += "\n NOT queuing: ";
if (download.isChecking())
sDebugLine += "can't auto-queue a checking torrent";
else if (!bOverLimit)
sDebugLine += "not over limit. numWaitingOrSeeding("
+ vars.numWaitingOrSeeding + ") <= maxSeeders("
+ totals.maxSeeders + ")";
else
sDebugLine += "bActivelySeeding=" + bActivelySeeding
+ ";bSeeding" + bSeeding;
}
} else {
if (bDebugLog)
sDebugLine += "\n Forcing a stop..";
}
if (okToStop) {
try {
if (state == Download.ST_READY)
totals.waitingToSeed--;
download.stopAndQueue();
vars.bStopAndQueued = true;
// okToQueue only allows READY and SEEDING state.. and in both cases
// we have to reduce counts
if (bActivelySeeding) {
totals.activelyCDing--;
bActivelySeeding = false;
vars.numWaitingOrSeeding--;
}
// force stop allows READY states in here, so adjust counts
if (state == Download.ST_READY)
totals.waitingToSeed--;
} catch (Exception ignore) {
/*ignore*/
}
state = download.getState();
}
}
// move completed timed rank types to bottom of the list
if (vars.bStopAndQueued && iRankType == RANK_TIMED) {
for (int j = 0; j < dlDataArray.length; j++) {
Download dl = dlDataArray[j].getDownloadObject();
int sr = dl.getSeedingRank();
if (sr > 0 && sr < DefaultRankCalculator.SR_TIMED_QUEUED_ENDS_AT) {
// Move everyone up
// We always start by setting SR to SR_TIMED_QUEUED_ENDS_AT - position
// then, the torrent with the biggest starts seeding which is
// (SR_TIMED_QUEUED_ENDS_AT - 1), leaving a gap.
// when it's time to stop the torrent, move everyone up, and put
// us at the end
dl.setSeedingRank(sr + 1);
}
}
rank = DefaultRankCalculator.SR_TIMED_QUEUED_ENDS_AT - totals.complete;
download.setSeedingRank(rank);
}
state = download.getState();
if (rank >= 0
&& (state == Download.ST_QUEUED || state == Download.ST_READY
|| state == Download.ST_WAITING || state == Download.ST_PREPARING)) {
vars.higherCDtoStart = true;
}
} finally {
if (bDebugLog) {
String[] debugEntries2 = new String[] {
"CD state=" + sStates.charAt(download.getState()),
"shareR=" + download.getStats().getShareRatio(),
"nWorCDing=" + vars.numWaitingOrSeeding,
"nWorDLing=" + vars.numWaitingOrDLing,
"sr=" + download.getSeedingRank(),
"hgherQd=" + boolDebug(vars.higherCDtoStart),
"maxCDrs=" + totals.maxSeeders,
"FP=" + boolDebug(isFP),
"nActCDing=" + totals.activelyCDing,
"ActCDing=" + boolDebug(dlData.getActivelySeeding())
};
printDebugChanges("", debugEntries, debugEntries2, sDebugLine, " ",
true, dlData);
}
}
}
private String boolDebug(boolean b) {
return b ? "Y" : "N";
}
private void printDebugChanges(String sPrefixFirstLine, String[] oldEntries,
String[] newEntries, String sDebugLine, String sPrefix,
boolean bAlwaysPrintNoChangeLine, DefaultRankCalculator dlData) {
boolean bAnyChanged = false;
String sDebugLineNoChange = sPrefixFirstLine;
String sDebugLineOld = "";
String sDebugLineNew = "";
for (int j = 0; j < oldEntries.length; j++) {
if (oldEntries[j].equals(newEntries[j]))
sDebugLineNoChange += oldEntries[j] + ";";
else {
sDebugLineOld += oldEntries[j] + ";";
sDebugLineNew += newEntries[j] + ";";
bAnyChanged = true;
}
}
String sDebugLineOut = ((bAlwaysPrintNoChangeLine || bAnyChanged)
? sDebugLineNoChange : "")
+ (bAnyChanged ? "\nOld:" + sDebugLineOld + "\nNew:" + sDebugLineNew
: "") + sDebugLine;
if (!sDebugLineOut.equals("")) {
String[] lines = sDebugLineOut.split("\n");
for (int i = 0; i < lines.length; i++) {
String s = sPrefix + ((i > 0) ? " " : "") + lines[i];
if (dlData == null) {
log.log(LoggerChannel.LT_INFORMATION, s);
} else {
log.log(dlData.dl.getTorrent(), LoggerChannel.LT_INFORMATION, s);
dlData.sTrace += s + "\n";
}
}
}
}
/**
* Get # of peers not including us
*
*/
public int calcPeersNoUs(Download download) {
int numPeers = 0;
DownloadScrapeResult sr = download.getLastScrapeResult();
if (sr.getScrapeStartTime() > 0) {
numPeers = sr.getNonSeedCount();
// If we've scraped after we started downloading
// Remove ourselves from count
if ((numPeers > 0) && (download.getState() == Download.ST_DOWNLOADING)
&& (sr.getScrapeStartTime() > download.getStats().getTimeStarted()))
numPeers--;
}
if (numPeers == 0) {
// Fallback to the # of peers we know of
DownloadAnnounceResult ar = download.getLastAnnounceResult();
if (ar != null
&& ar.getResponseType() == DownloadAnnounceResult.RT_SUCCESS)
numPeers = ar.getNonSeedCount();
if (numPeers == 0) {
DownloadActivationEvent activationState = download.getActivationState();
if (activationState != null) {
numPeers = activationState.getActivationCount();
}
}
}
return numPeers;
}
private boolean scrapeResultOk(Download download) {
DownloadScrapeResult sr = download.getLastScrapeResult();
return (sr.getResponseType() == DownloadScrapeResult.RT_SUCCESS);
}
/** Get # of seeds, not including us, AND including fake full copies
*
* @param download Download to get # of seeds for
* @return seed count
*/
public int calcSeedsNoUs(Download download) {
return calcSeedsNoUs(download, calcPeersNoUs(download));
}
/** Get # of seeds, not including us, AND including fake full copies
*
* @param download Download to get # of seeds for
* @param numPeers # peers we know of, required to calculate Fake Full Copies
* @return seed count
*/
public int calcSeedsNoUs(Download download, int numPeers) {
int numSeeds = 0;
DownloadScrapeResult sr = download.getLastScrapeResult();
if (sr.getScrapeStartTime() > 0) {
long seedingStartedOn = download.getStats().getTimeStartedSeeding();
numSeeds = sr.getSeedCount();
// If we've scraped after we started seeding
// Remove ourselves from count
if ((numSeeds > 0) && (seedingStartedOn > 0)
&& (download.getState() == Download.ST_SEEDING)
&& (sr.getScrapeStartTime() > seedingStartedOn))
numSeeds--;
}
if (numSeeds == 0) {
// Fallback to the # of seeds we know of
DownloadAnnounceResult ar = download.getLastAnnounceResult();
if (ar != null
&& ar.getResponseType() == DownloadAnnounceResult.RT_SUCCESS)
numSeeds = ar.getSeedCount();
}
if (numPeersAsFullCopy != 0 && numSeeds >= iFakeFullCopySeedStart)
numSeeds += numPeers / numPeersAsFullCopy;
return numSeeds;
}
/**
* Request that the startstop rules process. Used when it's known that
* something has changed that will effect torrent's state/position/rank.
*/
private long processMergeCount = 0;
public void requestProcessCycle(DefaultRankCalculator rankToRecalc) {
if (rankToRecalc != null) {
try {
this_mon.enter();
ranksToRecalc.add(rankToRecalc);
} finally {
this_mon.exit();
}
}
if (somethingChanged) {
processMergeCount++;
} else {
somethingChanged = true;
}
}
public void generate(IndentWriter writer) {
writer.println("StartStopRules Manager");
try {
writer.indent();
writer.println("Started " + (SystemTime.getCurrentTime() - startedOn)
+ "ms ago");
writer.println("downloadDataMap size = " + downloadDataMap.size());
if (changeCheckCount > 0) {
writer.println("changeCheck CPU ms: avg="
+ (changeCheckTotalMS / changeCheckCount) + "; max = "
+ changeCheckMaxMS);
}
if (processCount > 0) {
writer.println("# process cycles: " + processCount);
writer.println("process CPU ms: avg=" + (processTotalMS / processCount)
+ "; max = " + processMaxMS);
if (processCount > 1) {
writer.println("process avg gap: "
+ (processTotalGap / ((processCount - 1))) + "ms");
}
writer.println("Avg # recalcs per process cycle: "
+ (processTotalRecalcs / processCount));
if (processTotalZeroRecalcs > 0) {
writer.println("# process cycle with 0 recalcs: "
+ processTotalZeroRecalcs);
}
}
} catch (Exception e) {
// ignore
} finally {
writer.exdent();
}
}
} // class
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -