📄 defaultrankcalculator.java
字号:
/*
* Copyright (C) 2005, 2006 Aelitis, All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* AELITIS, SAS au capital de 46,603.30 euros
* 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
*
*/
package com.aelitis.azureus.plugins.startstoprules.defaultplugin;
import java.util.Map;
import org.gudy.azureus2.core3.config.COConfigurationListener;
import org.gudy.azureus2.core3.config.COConfigurationManager;
import org.gudy.azureus2.core3.util.AEMonitor;
import org.gudy.azureus2.core3.util.SystemTime;
import org.gudy.azureus2.plugins.PluginConfig;
import org.gudy.azureus2.plugins.download.Download;
import org.gudy.azureus2.plugins.download.DownloadScrapeResult;
import org.gudy.azureus2.plugins.download.DownloadStats;
import org.gudy.azureus2.plugins.logging.LoggerChannel;
/**
* @author TuxPaper
* @created Dec 13, 2005
*
*/
public class DefaultRankCalculator implements Comparable {
/** All of the First Priority rules must match */
public static final int FIRSTPRIORITY_ALL = 0;
/** Any of the First Priority rules must match */
public static final int FIRSTPRIORITY_ANY = 1;
/**
* Force torrent to be "Actively Seeding/Downloading" for this many ms upon
* start of torrent.
*/
private static final int FORCE_ACTIVE_FOR = 30000;
/**
* Wait XX ms before really changing activity (DL or CDing) state when
* state changes via speed change
*/
private static final int ACTIVE_CHANGE_WAIT = 10000;
/** Maximium ranking that a torrent can get using the SPRATIO ranking type */
private static int SPRATIO_BASE_LIMIT = 99999;
/**
* 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 int SEEDONLY_SHIFT = SPRATIO_BASE_LIMIT + 1;
/**
* For loading config settings
*/
private static COConfigurationListener configListener = null;
//
// Seeding Rank (SR) Limits and Values
/** Rank that complete starts at (and incomplete ends at + 1) */
public static final int SR_COMPLETE_STARTS_AT = 1000000000; // billion
/** Maximimum ranking for time queue mode. 1 unit is a second */
public static final int SR_TIMED_QUEUED_ENDS_AT = 999999; // 11.57 days
/** Ranks below this value are for torrents to be ignored (moved to bottom & queued) */
public static final int SR_IGNORED_LESS_THAN = -1;
/** Seeding Rank value when download is marked as not queued */
public static final int SR_NOTQUEUED = -2;
/** Seeding Rank value when download is marked as S:P Ratio Met for FP */
public static final int SR_FP_SPRATIOMET = -3;
/** Seeding Rank value when download is marked as P:1S Ratio Met */
public static final int SR_RATIOMET = -4;
/** Seeding Rank value when download is marked as # Seeds Met */
public static final int SR_NUMSEEDSMET = -5;
/** Seeding Rank value when download is marked as 0 Peers and FP */
public static final int SR_FP0PEERS = -6;
/** Seeding Rank value when download is marked as 0 Peers */
public static final int SR_0PEERS = -7;
/** Seeding Rank value when download is marked as Share Ratio Met */
public static final int SR_SHARERATIOMET = -8;
//
// Static config values
/** Ranking System to use */
protected static int iRankType = -1;
/** Min # of Peers needed before boosting the rank of downloads with no seeds */
private static int minPeersToBoostNoSeeds;
/** Min Speed needed to count a incomplete download as being actively downloading */
private static int minSpeedForActiveDL;
/** Min speed needed to count a complete download as being actively seeding */
private static int minSpeedForActiveSeeding;
// Ignore torrent if seed count is at least..
private static int iIgnoreSeedCount;
// Ignore even when First Priority
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;
// Ignore First Priority
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;
//
// Class variables
protected Download dl;
private boolean bActivelyDownloading;
private long lDLActivelyChangedOn;
private boolean bActivelySeeding;
private long lCDActivelyChangedOn;
private boolean bIsFirstPriority;
/** Public for tooltip to access it */
public String sExplainFP = "";
/** Public for tooltip to access it */
public String sExplainSR = "";
/** Public for tooltip to access it */
public String sTrace = "";
private AEMonitor downloadData_this_mon = new AEMonitor(
"StartStopRules:downloadData");
private final StartStopRulesDefaultPlugin rules;
/**
* Default Initializer
*
* @param _rules
* @param _dl
*/
public DefaultRankCalculator(StartStopRulesDefaultPlugin _rules, Download _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();
}
}
/**
* Load config values into the static variables
*
* @param cfg
*/
public static void reloadConfigParams(PluginConfig 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");
}
/** Sort first by SeedingRank Descending, then by Position Ascending.
*/
public int compareTo(Object obj) {
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 = rules.calcPeersNoUs(dlData.dl);
int numPeersUs = rules.calcPeersNoUs(dl);
if (bPreferLargerSwarms)
value = numPeersThem - numPeersUs;
else
value = numPeersUs - numPeersThem;
if (value != 0)
return value;
// Test Share Ratio
int shareRatioUs = dl.getStats().getShareRatio();
int shareRatioThem = dlData.dl.getStats().getShareRatio();
value = shareRatioUs - shareRatioThem;
if (value != 0)
return value;
}
// Test Position
return dl.getPosition() - dlData.dl.getPosition();
}
public Download getDownloadObject() {
return dl;
}
public boolean isForceActive() {
DownloadStats stats = dl.getStats();
return System.currentTimeMillis() - stats.getTimeStarted() <= FORCE_ACTIVE_FOR;
}
/**
* Retrieves whether the torrent is "actively" downloading
*
* @return true: actively downloading
*/
public boolean getActivelyDownloading() {
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 (System.currentTimeMillis() - stats.getTimeStarted() <= FORCE_ACTIVE_FOR) {
bIsActive = true;
} else {
// activity based on DL Average
bIsActive = (stats.getDownloadAverage() >= minSpeedForActiveDL);
if (bActivelyDownloading != bIsActive) {
long now = System.currentTimeMillis();
// 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;
}
/**
* Retrieves whether the torrent is "actively" seeding
*
* @return true: actively seeding
*/
public boolean getActivelySeeding() {
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 && scrapeResultOk(dl))) {
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 (System.currentTimeMillis() - stats.getTimeStarted() <= FORCE_ACTIVE_FOR) {
bIsActive = true;
} else {
bIsActive = (stats.getUploadAverage() >= minSpeedForActiveSeeding);
if (bActivelySeeding != bIsActive) {
long now = System.currentTimeMillis();
// 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;
}
/** Assign Seeding Rank based on RankType
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -