FileDocCategorySizeDatePackage
SpeedLimitMonitor.javaAPI DocAzureus 3.0.3.457325Tue Aug 14 07:44:54 BST 2007com.aelitis.azureus.core.speedmanager.impl.v2

SpeedLimitMonitor

public class SpeedLimitMonitor extends Object implements PSMonitorListener
This class is responsible for re-adjusting the limits used by AutoSpeedV2. This class will keep track of the "status" (i.e. seeding, downloading)of the application. It will then re-adjust the MAX limits when it thinks limits are being reached. Here are the rules it will use. #1) When seeding. If the upload is AT_LIMIT for a period of time it will allow that to adjust upward. #2) When downloading. If the download is AT_LIMIT for a period of time it will allow that to adjust upward. #3) When downloading, if a down-tick is detected and the upload is near a limit, it will drop the upload limit to 80% of MAX_UPLOAD. #4) Once that limit is reached it will drop both the upload and download limits together. #5) Seeding mode is triggered when - download bandwidth at LOW - compared to CAPACITY for 5 minutes continously. #6) Download mode is triggered when - download bandwidth reaches MEDIUM - compared to CURRENT_LIMIT for the first time. Rules #5 and #6 favor downloading over seeding.

Fields Summary
private int
uploadLimitMax
private int
uploadLimitMin
private int
downloadLimitMax
private int
downloadLimitMin
private TransferMode
transferMode
private SaturatedMode
uploadBandwidthStatus
private SaturatedMode
downloadBandwidthStatus
private SaturatedMode
uploadLimitSettingStatus
private SaturatedMode
downloadLimitSettingStatus
private SpeedLimitConfidence
uploadLimitConf
private SpeedLimitConfidence
downloadLimitConf
private long
clLastIncreaseTime
private long
clFirstBadPingTime
private boolean
currTestDone
private boolean
beginLimitTest
private int
highestUploadRate
private int
highestDownloadRate
private int
preTestUploadCapacity
private int
preTestUploadLimit
private int
preTestDownloadCapacity
private int
preTestDownloadLimit
public static final String
UPLOAD_CONF_LIMIT_SETTING
public static final String
DOWNLOAD_CONF_LIMIT_SETTING
public static final String
UPLOAD_CHOKE_PING_COUNT
private static final long
CONF_LIMIT_TEST_LENGTH
private boolean
isUploadMaxPinned
private boolean
isDownloadMaxPinned
private long
uploadAtLimitStartTime
private long
downloadAtLimitStartTime
private int
uploadChokePingCount
private int
uploadPinCounter
private static final long
TIME_AT_LIMIT_BEFORE_UNPINNING
public static final String
USED_UPLOAD_CAPACITY_DOWNLOAD_MODE
public static final String
USED_UPLOAD_CAPACITY_SEEDING_MODE
private float
percentUploadCapacityDownloadMode
PingSpaceMapper
pingMapOfDownloadMode
PingSpaceMapper
pingMapOfSeedingMode
boolean
useVariancePingMap
com.aelitis.azureus.core.speedmanager.SpeedManagerPingMapper
transientPingMap
PingSpaceMon
longTermMonitor
LimitControl
slider
SpeedLimitListener
persistentMapListener
Constructors Summary
public SpeedLimitMonitor(com.aelitis.azureus.core.speedmanager.SpeedManager sm)


      

        //
        longTermMonitor.addListener( this );
        
        persistentMapListener = new SpeedLimitListener( this );

        sm.addListener( persistentMapListener );
    
Methods Summary
public voidaddToPingMapData(int lastMetricValue)

        String modeStr = getTransferModeAsString();

        if(    modeStr.equalsIgnoreCase(TransferMode.State.DOWNLOADING.getString())
            || modeStr.equalsIgnoreCase(TransferMode.State.DOWNLOAD_LIMIT_SEARCH.getString())  )
        {
            //add point to map for download mode
            pingMapOfDownloadMode.addMetricToMap(lastMetricValue);

        }
        else if(     modeStr.equalsIgnoreCase(TransferMode.State.SEEDING.getString())
                  || modeStr.equalsIgnoreCase(TransferMode.State.UPLOAD_LIMIT_SEARCH.getString()) )
        {
            //add point to map for seeding mode.
            pingMapOfSeedingMode.addMetricToMap(lastMetricValue);

        }


        //if confidence limit testing, inform of bad ping.
        updateLimitTestingPing(lastMetricValue);

        longTermMonitor.updateStatus(transferMode);

    
public SMUpdateadjustLimitsToSpec(int currUploadLimit, int currDownloadLimit)
It is likely the user adjusted the "line speed capacity" on the configuration panel. We need to adjust the current limits down to adjust.

param
currUploadLimit -
param
currDownloadLimit -
return
- Updates as needed.


        int newUploadLimit = currUploadLimit;
        boolean uploadChanged = false;
        int newDownloadLimit = currDownloadLimit;
        boolean downloadChanged = false;

        StringBuffer reason = new StringBuffer();

        //check for the case when the line-speed capacity is below the current limit.
        if( currUploadLimit> uploadLimitMax && uploadLimitMax!=0){

            newUploadLimit = uploadLimitMax;
            uploadChanged = true;

            reason.append(" (a) upload line-speed cap below current limit. ");
        }

        if(uploadLimitMax==0){
            reason.append("** uploadLimitMax=0 (Unlimited)! ** ");
        }

        //check for the case when the min setting has been moved above the current limit.
        if( currDownloadLimit> downloadLimitMax && !slider.isDownloadUnlimitedMode() ){
            newDownloadLimit = downloadLimitMax;
            downloadChanged = true;

            reason.append(" (b) download line-speed cap below current limit. ");
        }

        //Another possibility is the min limits have been raised.
        if( currUploadLimit<uploadLimitMin ){
            newUploadLimit = uploadLimitMin;
            uploadChanged = true;

            reason.append(" (c) min upload limit raised. ");
        }

        if( currDownloadLimit<downloadLimitMin ){
            newDownloadLimit = downloadLimitMin;
            downloadChanged = true;

            reason.append(" (d)  min download limit raised. ");
        }

        SpeedManagerLogger.trace("Adjusting limits due to out of spec: new-up="+newUploadLimit
                +" new-down="+newDownloadLimit+"  reasons: "+reason.toString());

        return new SMUpdate(newUploadLimit,uploadChanged,newDownloadLimit,downloadChanged);
    
public booleanareSettingsInSpec(int currUploadLimit, int currDownloadLimit)
If the user changes the line capacity settings on the configuration panel and adjustment needs to occur even if the signal is NO-CHANGE-NEEDED. Test for that condition here.

param
currUploadLimit - reported upload capacity from the adapter
param
currDownloadLimit - reported download capacity from the adapter.
return
- true if the "capacity" is lower then the current limit.


        //during a confidence level test, anything goes.
        if( isConfTestingLimits() ){
            return true;
        }

        boolean retVal = true;
        if( currUploadLimit> uploadLimitMax){
            retVal = false;
        }
        if(  currDownloadLimit> downloadLimitMax && slider.isDownloadUnlimitedMode() ){
            retVal = false;
        }
        return retVal;
    
public booleanbandwidthUsageAtLimit()
True if both are at limits.

return
- true only if both the upload and download usages are at the limits.

        if( uploadBandwidthStatus.compareTo(SaturatedMode.AT_LIMIT)==0 &&
                downloadBandwidthStatus.compareTo(SaturatedMode.AT_LIMIT)==0){
            return true;
        }
        return false;
    
public booleanbandwidthUsageLow()
Are both the upload and download bandwidths usages is low? Otherwise false.

return
-


        if( uploadBandwidthStatus.compareTo(SaturatedMode.LOW)<=0 &&
                downloadBandwidthStatus.compareTo(SaturatedMode.LOW)<=0){

            return true;

        }

        //Either upload or download is at MEDIUM or above.
        return false;
    
public booleanbandwidthUsageMedium()

return
-

        if( uploadBandwidthStatus.compareTo(SaturatedMode.MED)<=0 &&
                downloadBandwidthStatus.compareTo(SaturatedMode.MED)<=0){
            return true;
        }

        //Either upload or download is at MEDIUM or above.
        return false;
    
public voidbetaLogPingMapperEstimates(java.lang.String name, com.aelitis.azureus.core.speedmanager.SpeedManagerLimitEstimate transEst, boolean hadChockPing, com.aelitis.azureus.core.speedmanager.SpeedManagerLimitEstimate permEst, PingSpaceMapper downMode, PingSpaceMapper seedMode)
This is a lot of data, but is important debug info.

param
name -
param
transEst -
param
hadChockPing -
param
permEst -
param
downMode -
param
seedMode -

        StringBuffer sb = new StringBuffer("beta-ping-maps-").append(name).append(": ");

        if(transEst!=null){
            int rate = transEst.getBytesPerSec();
            float conf = transEst.getMetricRating();
            sb.append("transient-").append(rate).append("(").append(conf).append(")");
        }
        sb.append(" chockPing=").append(hadChockPing);
 

        if(permEst!=null){
            int rate = permEst.getBytesPerSec();
            float conf = permEst.getMetricRating();
            sb.append("; perm-").append(rate).append("(").append(conf).append(")");
        }

        if(downMode!=null){
            int rateDown = downMode.guessDownloadLimit();
            int rateUp = downMode.guessUploadLimit();
            boolean downChockPing = downMode.hadChockingPing(true);
            boolean upChockPing = downMode.hadChockingPing(false);

            sb.append("; downMode- ");
            sb.append("rateDown=").append(rateDown).append(" ");
            sb.append("rateUp=").append(rateUp).append(" ");
            sb.append("downChockPing=").append(downChockPing).append(" ");
            sb.append("upChockPing=").append(upChockPing).append(" ");
        }

        if(seedMode!=null){
            int rateDown = seedMode.guessDownloadLimit();
            int rateUp = seedMode.guessUploadLimit();
            boolean downChockPing = seedMode.hadChockingPing(true);
            boolean upChockPing = seedMode.hadChockingPing(false);

            sb.append("; seedMode- ");
            sb.append("rateDown=").append(rateDown).append(" ");
            sb.append("rateUp=").append(rateUp).append(" ");
            sb.append("downChockPing=").append(downChockPing).append(" ");
            sb.append("upChockPing=").append(upChockPing).append(" ");
        }
        SpeedManagerLogger.log( sb.toString() );
    
public SMUpdatecalculateNewUnpinnedLimits(float signalStrength)

param
signalStrength -
return
-


        //first verify that is this is an up signal.
        if(signalStrength<0.0f){
            //down-tick is a signal to stop moving the files up.
            isUploadMaxPinned=true;
            isDownloadMaxPinned=true;
        }//if

        //just verify settings to make sure everything is sane before updating.
        boolean updateUpload=false;
        boolean updateDownload=false;

        if( uploadBandwidthStatus.compareTo(SaturatedMode.AT_LIMIT)==0 &&
                uploadLimitSettingStatus.compareTo(SaturatedMode.AT_LIMIT)==0 ){
            updateUpload=true;
        }

        if( downloadBandwidthStatus.compareTo(SaturatedMode.AT_LIMIT)==0 &&
                downloadLimitSettingStatus.compareTo(SaturatedMode.AT_LIMIT)==0 ){
            updateDownload=true;
        }

        boolean uploadChanged=false;
        boolean downloadChanged=false;


        if(updateUpload && !transferMode.isDownloadMode() ){
            //slow the upload rate the more.
            uploadPinCounter++;
            if( uploadPinCounter%(Math.ceil(Math.sqrt(uploadChokePingCount)))==0 ){
                //increase limit by calculated amount, but only if not in downloading mode.
                uploadLimitMax += calculateUnpinnedStepSize(uploadLimitMax);
                uploadChanged=true;
                COConfigurationManager.setParameter(
                        SpeedManagerAlgorithmProviderV2.SETTING_UPLOAD_MAX_LIMIT, uploadLimitMax);
                COConfigurationManager.setParameter(
                        SpeedLimitMonitor.UPLOAD_CHOKE_PING_COUNT,uploadChokePingCount);
            }//if
        }
        if(updateDownload && !slider.isDownloadUnlimitedMode() ){
            //increase limit by calculated amount.
            downloadLimitMax += calculateUnpinnedStepSize(downloadLimitMax);
            downloadChanged=true;
            COConfigurationManager.setParameter(
                    SpeedManagerAlgorithmProviderV2.SETTING_DOWNLOAD_MAX_LIMIT, downloadLimitMax);
        }

        //apply any rules that need applied.
        //The download limit can never be less then the upload limit. (Unless zero. UNLIMITED)
        if( uploadLimitMax > downloadLimitMax){
            downloadLimitMax = uploadLimitMax;
            downloadChanged=true;
            COConfigurationManager.setParameter(
                    SpeedManagerAlgorithmProviderV2.SETTING_DOWNLOAD_MAX_LIMIT, downloadLimitMax);
        }

        uploadLimitMin = SMConst.calculateMinUpload( uploadLimitMax );
        downloadLimitMin = SMConst.calculateMinDownload( downloadLimitMax );

        if( slider.isDownloadUnlimitedMode() ){
            SpeedManagerLogger.trace("upload unpinned while download is unlimited.");
            return new SMUpdate(uploadLimitMax,uploadChanged, 0,false);
        }

        return new SMUpdate(uploadLimitMax,uploadChanged, downloadLimitMax,downloadChanged);
    
private intcalculateUnpinnedStepSize(int currLimitMax)
If setting is less then 100kBytes take 1 kByte steps. If setting is less then 500kBytes take 5 kByte steps. if setting is larger take 10 kBytes steps.

param
currLimitMax - current limit setting.
return
- set size for next change.

        if(currLimitMax<102400){
            return 1024;
        }else if(currLimitMax<409600){
            return 1024*5;
        }else if(currLimitMax>=409600){
            return 1024*10;
        }
        return 1024;
    
public voidcheckForUnpinningCondition()
Make a decision about unpinning either the upload or download limit. This is based on the time we are saturating the limit without a down-tick signal.


        long currTime = SystemTime.getCurrentTime();

        //verify the download is not unlimited.
        slider.setDownloadUnlimitedMode( isSettingDownloadUnlimited() );

        //upload useage must be at limits for a set period of time before unpinning.
        if( !uploadBandwidthStatus.equals(SaturatedMode.AT_LIMIT) ||
                !uploadLimitSettingStatus.equals(SaturatedMode.AT_LIMIT) )
        {
            //start the clock over.
            uploadAtLimitStartTime = currTime;
        }else{
            //check to see if we have been here for the time limit.
            if( uploadAtLimitStartTime+(TIME_AT_LIMIT_BEFORE_UNPINNING* uploadChokePingCount) < currTime ){

                if( isUploadConfidenceLow() ){
                    if( !transferMode.isDownloadMode() ){
                        //alway slow search the upload limit.
                        isUploadMaxPinned = false; 
                    }
                }else{
                    //Don't unpin the limit is we have absolute confidence in it.
                    if( !isUploadConfidenceAbsolute() ){
                        //we have been AT_LIMIT long enough. Time to un-pin the limit see if we can go higher.
                        isUploadMaxPinned = false;
                        SpeedManagerLogger.trace("unpinning the upload max limit!! #choke-pings="+uploadChokePingCount+
                            ", pin-counter="+uploadPinCounter);
                    }
                }
            }
        }

        //download usage must be at limits for a set period of time before unpinning.
        if( !downloadBandwidthStatus.equals(SaturatedMode.AT_LIMIT) ||
                !downloadLimitSettingStatus.equals(SaturatedMode.AT_LIMIT) )
        {
            //start the clock over.
            downloadAtLimitStartTime = currTime;
        }else{
            //check to see if we have been here for the time limit.
            if( downloadAtLimitStartTime+TIME_AT_LIMIT_BEFORE_UNPINNING < currTime ){

                if( isDownloadConfidenceLow() ){
                    if( transferMode.isDownloadMode() ){
                        triggerLimitTestingFlag();
                    }
                }else{
                    if( !isDownloadConfidenceAbsolute() ){
                        //we have been AT_LIMIT long enough. Time to un-pin the limit see if we can go higher.
                        isDownloadMaxPinned = false;
                        SpeedManagerLogger.trace("unpinning the download max limit!!");
                    }
                }
            }
        }

        logPinningInfo();
    
private intchoseBestLimit(com.aelitis.azureus.core.speedmanager.SpeedManagerLimitEstimate estimate, int currMaxLimit, SpeedLimitConfidence currConf)

        float type = estimate.getEstimateType();
        int estBytesPerSec = estimate.getBytesPerSec();
        int chosenLimit;

        //no estimate less then 20k accepted.
        if( (estBytesPerSec<currMaxLimit) && estBytesPerSec<20480 ){
            return currMaxLimit;
        }

        String reason="";
        if(  type==SpeedManagerLimitEstimate.TYPE_MANUAL){
            chosenLimit = estBytesPerSec;
            reason="manual";
        }else if( type==SpeedManagerLimitEstimate.TYPE_UNKNOWN){
            chosenLimit = Math.max( estBytesPerSec, currMaxLimit );
            reason="unknown";
        }else{            
            //chose ping mapper.
            chosenLimit = estBytesPerSec;
        }

        SpeedManagerLogger.trace("bestChosenLimit: reason="+reason+",chosenLimit="+chosenLimit);

        return chosenLimit;
    
public SpeedLimitConfidencedetermineConfidenceLevel()
After a test is complete determine how condifent the client should be in it based on how different it is from the previous result. If the new result is within 20% of the old result then give it a MED. If it is great then give it a LOW.

return
- what the new confidence interval should be.

        SpeedLimitConfidence retVal=SpeedLimitConfidence.NONE;
        String settingMaxLimitName;
        //String settingMinLimitName;
        boolean isDownload;
        String settingConfidenceName;
        int preTestValue;
        int highestValue;
        if(transferMode.getMode()==TransferMode.State.DOWNLOAD_LIMIT_SEARCH){

            settingConfidenceName = DOWNLOAD_CONF_LIMIT_SETTING;
            settingMaxLimitName = SpeedManagerAlgorithmProviderV2.SETTING_DOWNLOAD_MAX_LIMIT;
            isDownload=true;
            preTestValue = preTestDownloadCapacity;
            highestValue = highestDownloadRate;
        }else if(transferMode.getMode()==TransferMode.State.UPLOAD_LIMIT_SEARCH){

            settingConfidenceName = UPLOAD_CONF_LIMIT_SETTING;
            settingMaxLimitName = SpeedManagerAlgorithmProviderV2.SETTING_UPLOAD_MAX_LIMIT;
            isDownload=false;
            preTestValue = preTestUploadCapacity;
            highestValue = highestUploadRate;
        }else{
            //
            SpeedManagerLogger.log("IllegalState in determineConfidenceLevel(). Setting level to NONE.");
            return SpeedLimitConfidence.NONE;
        }

        boolean hadChockingPing = hadChockingPing();
        float percentDiff = (float)Math.abs( highestValue-preTestValue )/(float)(Math.max(highestValue,preTestValue));
        if( percentDiff<0.15f  && hadChockingPing ){
            //Only set to medium if had both a chocking ping and two tests with similar results.
            retVal = SpeedLimitConfidence.MED;
        }else{
            retVal = SpeedLimitConfidence.LOW;
        }

        //update the values.
        COConfigurationManager.setParameter(settingConfidenceName, retVal.getString() );
        int newMaxLimitSetting = highestValue;
        COConfigurationManager.setParameter(settingMaxLimitName, newMaxLimitSetting);
        int newMinLimitSetting;
        if( isDownload ){
            newMinLimitSetting = SMConst.calculateMinDownload( newMaxLimitSetting );
        }else{
            newMinLimitSetting = SMConst.calculateMinUpload( newMaxLimitSetting );
        }

        StringBuffer sb = new StringBuffer();
        if( transferMode.getMode()==TransferMode.State.UPLOAD_LIMIT_SEARCH ){
            sb.append("new upload limits: ");
            uploadLimitMax =newMaxLimitSetting;
            uploadLimitMin=newMinLimitSetting;
            //downloadCapacity can never be less then upload capacity.
            if( downloadLimitMax < uploadLimitMax){
                downloadLimitMax = uploadLimitMax;
                COConfigurationManager.setParameter(
                        SpeedManagerAlgorithmProviderV2.SETTING_DOWNLOAD_MAX_LIMIT, downloadLimitMax);
            }
            sb.append(uploadLimitMax);
        }else{
            sb.append("new download limits: ");
            downloadLimitMax =newMaxLimitSetting;
            downloadLimitMin=newMinLimitSetting;
            //upload capacity should never be 40x less then download.
            if( uploadLimitMax * 40 < downloadLimitMax){
                uploadLimitMax = downloadLimitMax /40;
                COConfigurationManager.setParameter(
                         SpeedManagerAlgorithmProviderV2.SETTING_UPLOAD_MAX_LIMIT, uploadLimitMax);

                uploadLimitMin = SMConst.calculateMinUpload( uploadLimitMax );
            }//if
            sb.append(downloadLimitMax);
        }

        slider.updateLimits(uploadLimitMax,uploadLimitMin,downloadLimitMax,downloadLimitMin);

        SpeedManagerLogger.trace( sb.toString() );

        return retVal;
    
public synchronized SMUpdateendLimitTesting(int downloadCapacityGuess, int uploadCapacityGuess)


        SpeedManagerLogger.trace(" repalce highestDownloadRate: "+highestDownloadRate+" with "+downloadCapacityGuess);
        SpeedManagerLogger.trace(" replace highestUploadRate: "+highestUploadRate+" with "+uploadCapacityGuess);

        highestDownloadRate = downloadCapacityGuess;
        highestUploadRate = uploadCapacityGuess;

        return endLimitTesting();
    
public synchronized SMUpdateendLimitTesting()
Call this method to end the limit testing.

return
- SMUpdate


        SMUpdate retVal;
        //determine if the new setting is different then the old setting.
        if( transferMode.getMode()==TransferMode.State.DOWNLOAD_LIMIT_SEARCH ){

            downloadLimitConf = determineConfidenceLevel();

            //set that value.
            SpeedManagerLogger.trace("pre-upload-setting="+ preTestUploadCapacity +" up-capacity"+ uploadLimitMax
                    +" pre-download-setting="+ preTestDownloadCapacity +" down-capacity="+ downloadLimitMax);

            retVal = new SMUpdate(preTestUploadLimit,true, downloadLimitMax,true);
            //change back to original mode.
            transferMode.setMode( TransferMode.State.DOWNLOADING );

        }else if( transferMode.getMode()==TransferMode.State.UPLOAD_LIMIT_SEARCH){

            uploadLimitConf = determineConfidenceLevel();

            //set that value.
            retVal = new SMUpdate(uploadLimitMax,true, downloadLimitMax,true);
            //change back to original mode.
            transferMode.setMode( TransferMode.State.SEEDING );

        }else{
            //This is an "illegal state" make it in the logs, but try to recover by setting back to original state.
            SpeedManagerLogger.log("SpeedLimitMonitor had IllegalState during endLimitTesting.");
            retVal = new SMUpdate(preTestUploadLimit,true, preTestDownloadLimit,true);
        }

        currTestDone=true;

        //reset the counter
        uploadAtLimitStartTime = SystemTime.getCurrentTime();
        downloadAtLimitStartTime = SystemTime.getCurrentTime();

        return retVal;
    
public SaturatedModegetDownloadBandwidthMode()

        return downloadBandwidthStatus;
    
public java.lang.StringgetDownloadConfidence()

        return downloadLimitConf.getString();
    
public SaturatedModegetDownloadLimitSettingMode()

        return downloadLimitSettingStatus;
    
public intgetDownloadMaxLimit()

        return downloadLimitMax;
    
public intgetDownloadMinLimit()

        return downloadLimitMin;
    
public TransferModegetTransferMode()

        return transferMode;
    
public java.lang.StringgetTransferModeAsString()

        return transferMode.getString();
    
public SaturatedModegetUploadBandwidthMode()

        return uploadBandwidthStatus;
    
public java.lang.StringgetUploadConfidence()

        return uploadLimitConf.getString();
    
public SaturatedModegetUploadLimitSettingMode()

        return uploadLimitSettingStatus;
    
public intgetUploadMaxLimit()

        return uploadLimitMax;
    
public intgetUploadMinLimit()

        return uploadLimitMin;
    
public intguessDownloadLimit()


        if( !useVariancePingMap){
            return pingMapOfDownloadMode.guessDownloadLimit();
        }else{

            boolean wasChocked=true;
            SpeedManagerLimitEstimate transientEst=null;
            if(transientPingMap!=null){
                transientEst = transientPingMap.getLastBadDownloadLimit();
                if(transientEst==null){
                    wasChocked=false;
                    transientEst = transientPingMap.getEstimatedDownloadLimit(false);
                }
            }

            //NOTE: Currently just getting the persistentMap for temp logging purposes.
            SMInstance pm = SMInstance.getInstance();
            SpeedManagerAlgorithmProviderAdapter adapter = pm.getAdapter();
            SpeedManagerPingMapper persistentMap = adapter.getPingMapper();
            SpeedManagerLimitEstimate persistentEst = persistentMap.getEstimatedDownloadLimit(false);

            //log the different ping-mappers for beta.
            betaLogPingMapperEstimates("down",transientEst,wasChocked,persistentEst,pingMapOfDownloadMode,pingMapOfSeedingMode);

            if( transientEst!=null )
            {
                return choseBestLimit(transientEst,downloadLimitMax,downloadLimitConf);
            }else{
                return downloadLimitMax;
            }

        }
    
public intguessUploadLimit()


        if( !useVariancePingMap){

            int dmUpLimitGuess = pingMapOfDownloadMode.guessUploadLimit();
            int smUpLimitGuess = pingMapOfSeedingMode.guessUploadLimit();

            return Math.max(dmUpLimitGuess,smUpLimitGuess);

        }else{

            boolean wasChocked=true;
            SpeedManagerLimitEstimate transientEst=null;
            if(transientPingMap!=null){
                transientEst = transientPingMap.getLastBadUploadLimit();
                if(transientEst==null){
                    wasChocked=false;
                    transientEst = transientPingMap.getEstimatedUploadLimit(false);
                }
            }

            //NOTE: Currently just getting the persistentMap for temp logging purposes.
            SMInstance pm = SMInstance.getInstance();
            SpeedManagerAlgorithmProviderAdapter adapter = pm.getAdapter();
            SpeedManagerPingMapper persistentMap = adapter.getPingMapper();
            SpeedManagerLimitEstimate persistentEst = persistentMap.getEstimatedUploadLimit(false);

            //log the different ping-mappers for beta.
            betaLogPingMapperEstimates("up",transientEst,wasChocked,persistentEst,pingMapOfDownloadMode,pingMapOfSeedingMode);

            if( transientEst!=null )
            {
                return choseBestLimit(transientEst,uploadLimitMax,uploadLimitConf);
            }else{
                return uploadLimitMax;
            }
        }

    
public booleanhadChockingPing()
Should return true if had a recent chocking ping.

return
- true if

        if( !useVariancePingMap){

            return pingMapOfDownloadMode.hadChockingPing(true);

        }else{
            SpeedManagerPingMapper pm = SMInstance.getInstance().getAdapter().getPingMapper();

            //if either had a choking ping.
            SpeedManagerLimitEstimate dEst = pm.getEstimatedDownloadLimit(true);
            SpeedManagerLimitEstimate uEst = pm.getEstimatedUploadLimit(true);

            boolean hadChokePingUp = (uEst.getEstimateType()==SpeedManagerLimitEstimate.TYPE_CHOKE_ESTIMATED);
            boolean hadChokePingDown = (dEst.getEstimateType()==SpeedManagerLimitEstimate.TYPE_CHOKE_ESTIMATED);

            return ( hadChokePingUp || hadChokePingDown );
        }        
    
public voidinitPingSpaceMap(int maxGoodPing, int minBadPing)

        pingMapOfDownloadMode = new PingSpaceMapper(maxGoodPing,minBadPing);
        pingMapOfSeedingMode = new PingSpaceMapper(maxGoodPing,minBadPing);

        //pingMonitor = new PingSpaceMonitor(maxGoodPing,minBadPing,transferMode);

        useVariancePingMap = false;
    
public voidinitPingSpaceMap()

        useVariancePingMap = true;


        //ToDo: remove after beta-testing - just to characterize the different methods.
//        pingMapOfDownloadMode = new PingSpaceMapper(150,500);
//        pingMapOfSeedingMode = new PingSpaceMapper(150,500);

    
public synchronized booleanisConfLimitTestFinished()

        return currTestDone;
    
public booleanisConfTestingLimits()
Return true if we are confidence testing the limits.

return
- SMUpdate

        return transferMode.isConfTestingLimits();
    
public booleanisDownloadConfidenceAbsolute()

        return ( downloadLimitConf.compareTo(SpeedLimitConfidence.ABSOLUTE)==0 );
    
public booleanisDownloadConfidenceLow()
Determine if we have low confidence in this limit.

return
- true if the confidence setting is LOW or NONE. Otherwise return true.

        return ( downloadLimitConf.compareTo(SpeedLimitConfidence.MED) < 0 );
    
public booleanisEitherLimitUnpinned()

        return ( !isUploadMaxPinned || !isDownloadMaxPinned );
    
private booleanisSettingDownloadUnlimited()
The criteria for download being unlimited is if the ConfigPanel has the "download == 0 " && "type==fixed"

return
- true


        SpeedManagerAlgorithmProviderAdapter adpter = SMInstance.getInstance().getAdapter();

        SpeedManager sm = adpter.getSpeedManager();
        SpeedManagerLimitEstimate dEst = sm.getEstimatedDownloadCapacityBytesPerSec();

        int rate = dEst.getBytesPerSec();
        float type = dEst.getEstimateType();

        //user or plug-in want the download rate unlimited.
        if( rate==0 && type==SpeedManagerLimitEstimate.TYPE_MANUAL ){
            return true;
        }

        //start the search in unlimited mode.
        if( rate==0 && type==SpeedManagerLimitEstimate.TYPE_UNKNOWN){
            return true;
        }

        return false;
    
public synchronized booleanisStartLimitTestFlagSet()

        return beginLimitTest;
    
public booleanisUploadBandwidthUsageHigh()
True if the upload bandwidth usage is HIGH or AT_LIMIT.

return
-

        if( uploadBandwidthStatus.compareTo(SaturatedMode.AT_LIMIT)==0 ||
                uploadBandwidthStatus.compareTo(SaturatedMode.HIGH)==0){
            return true;
        }
        return false;
    
public booleanisUploadConfidenceAbsolute()

        return ( uploadLimitConf.compareTo(SpeedLimitConfidence.ABSOLUTE)==0 );
    
public booleanisUploadConfidenceLow()

        return ( uploadLimitConf.compareTo(SpeedLimitConfidence.MED) < 0 );
    
protected voidlog(java.lang.String str)


        SpeedManagerLogger.log(str);
    
private voidlogPMData(int oRate, SpeedLimitConfidence oConf, int nRate, float nConf, java.lang.String type)


        SpeedManagerLogger.log("speed-limit-conf: "+type+" rate="+oRate+" conf="+oConf.getString()+"("+oConf.asEstimateType()
                +") pm-rate="+nRate+" pm-conf="+nConf);

    
public voidlogPMDataEx()


        int tuploadLimitMax = COConfigurationManager.getIntParameter(SpeedManagerAlgorithmProviderV2.SETTING_UPLOAD_MAX_LIMIT);
        int tdownloadLimitMax =COConfigurationManager.getIntParameter(SpeedManagerAlgorithmProviderV2.SETTING_DOWNLOAD_MAX_LIMIT);

        //for testing.
        SpeedManager sm = AzureusCoreFactory.getSingleton().getSpeedManager();
        SpeedManagerLimitEstimate dEst = sm.getEstimatedDownloadCapacityBytesPerSec();

        int tmpDMax = dEst.getBytesPerSec();
        float tmpDMaxConf = dEst.getEstimateType();


        // for testing.
        SpeedManagerLimitEstimate uEst = sm.getEstimatedUploadCapacityBytesPerSec();
        int tmpUMax = uEst.getBytesPerSec();
        float tmpUMaxConf = uEst.getEstimateType();

        SpeedLimitConfidence tuploadLimitConf = SpeedLimitConfidence.parseString(
                COConfigurationManager.getStringParameter( SpeedLimitMonitor.UPLOAD_CONF_LIMIT_SETTING ));
        SpeedLimitConfidence tdownloadLimitConf = SpeedLimitConfidence.parseString(
                COConfigurationManager.getStringParameter( SpeedLimitMonitor.DOWNLOAD_CONF_LIMIT_SETTING));

        //
        logPMData(tuploadLimitMax, tuploadLimitConf, tmpUMax, tmpUMaxConf, "check-upload" );
        logPMData(tdownloadLimitMax, tdownloadLimitConf, tmpDMax, tmpDMaxConf, "check-download" );
        
    
public voidlogPingMapData()
Just log this data until we decide if it is useful.


        if( !useVariancePingMap){
            int downLimGuess = pingMapOfDownloadMode.guessDownloadLimit();
            int upLimGuess = pingMapOfDownloadMode.guessUploadLimit();
            int seedingUpLimGuess = pingMapOfSeedingMode.guessUploadLimit();

            StringBuffer sb = new StringBuffer("ping-map: ");
            sb.append(":down=").append(downLimGuess);
            sb.append(":up=").append(upLimGuess);
            sb.append(":(seed)up=").append(seedingUpLimGuess);

            SpeedManagerLogger.log( sb.toString()  );
        }else{
            SMInstance pm = SMInstance.getInstance();
            SpeedManagerAlgorithmProviderAdapter adapter = pm.getAdapter();
            SpeedManagerPingMapper persistentMap = adapter.getPingMapper();

            SpeedManagerLimitEstimate estUp = persistentMap.getEstimatedUploadLimit(false);
            SpeedManagerLimitEstimate estDown = persistentMap.getEstimatedDownloadLimit(false);

            int downLimGuess = estDown.getBytesPerSec();
            float downConf = estDown.getMetricRating();
            int upLimGuess = estUp.getBytesPerSec();
            float upConf = estUp.getMetricRating();

            String name = persistentMap.getName();

            StringBuffer sb = new StringBuffer("new-ping-map: ");
            sb.append(" name=").append(name);
            sb.append(", down=").append(downLimGuess);
            sb.append(", down-conf=").append(downConf);
            sb.append(", up=").append(upLimGuess);
            sb.append(", up-conf=").append(upConf);

            SpeedManagerLogger.log( sb.toString() );
        }
    
private voidlogPinningInfo()
Log debug info needed during beta period.

        StringBuffer sb = new StringBuffer("pin: ");
        if(isUploadMaxPinned){
            sb.append("ul-pinned:");
        }else{
            sb.append("ul-unpinned:");
        }
        if(isDownloadMaxPinned){
            sb.append("dl-pinned:");
        }else{
            sb.append("dl-unpinned:");
        }
        long currTime = SystemTime.getCurrentTime();
        long upWait = currTime - uploadAtLimitStartTime;
        long downWait = currTime - downloadAtLimitStartTime;
        sb.append(upWait).append(":").append(downWait);
        log( sb.toString() );
    
public SMUpdatemodifyLimits(float signalStrength, float multiple, int currUpLimit, int currDownLimit)
Does the same as createNewLimit except it drops the upload rate first when in download mode.

param
signalStrength -
param
multiple -
param
currUpLimit -
param
currDownLimit -
return
-


        //this flag is set in a previous method.
        if( isStartLimitTestFlagSet() ){
            SpeedManagerLogger.trace("modifyLimits - startLimitTesting.");
            return startLimitTesting(currUpLimit, currDownLimit);
        }


        if( isEitherLimitUnpinned() ){
            SpeedManagerLogger.trace("modifyLimits - calculateNewUnpinnedLimits");
            return calculateNewUnpinnedLimits(signalStrength);
        }

        slider.updateLimits(uploadLimitMax,uploadLimitMin,
                downloadLimitMax,downloadLimitMin);
        
        slider.updateStatus(currUpLimit,uploadBandwidthStatus,
                currDownLimit, downloadBandwidthStatus,transferMode);

        return slider.adjust( signalStrength*multiple );
    
public voidnotifyDownload(com.aelitis.azureus.core.speedmanager.SpeedManagerLimitEstimate estimate)

        int bestLimit = choseBestLimit(estimate,downloadLimitMax,downloadLimitConf);

        SpeedManagerLogger.trace("notifyDownload downloadLimitMax="+downloadLimitMax
                +" conf="+downloadLimitConf.getString()+" ("+downloadLimitConf.asEstimateType()+")");
        tempLogEstimate(estimate);

        if(downloadLimitMax!=bestLimit){
            //update COConfiguration
            SpeedManagerLogger.log( "persistent PingMap changed download limit to "+bestLimit );
            downloadLimitMax = bestLimit;
            COConfigurationManager.setParameter(
                    SpeedManagerAlgorithmProviderV2.SETTING_DOWNLOAD_MAX_LIMIT, bestLimit);
        }

        downloadLimitMin = SMConst.calculateMinDownload(downloadLimitMax);
        slider.updateLimits(uploadLimitMax,uploadLimitMin,downloadLimitMax,downloadLimitMin);


        if(estimate.getBytesPerSec()!=0){
            slider.setDownloadUnlimitedMode(false);
        }else{
            slider.setDownloadUnlimitedMode(true);
        }

        SMSearchLogger.log("download "+downloadLimitMax );         
    
public voidnotifyOfDownSignal()
If we have a down-tick signal then resetTimer all the counters for increasing the limits.


        if( !isUploadMaxPinned ){
            uploadChokePingCount++;
            String msg = "pinning the upload max limit, due to downtick signal. #downtick="+ uploadChokePingCount;
            SpeedManagerLogger.trace(msg);
            SMSearchLogger.log(msg);
        }

        if( !isDownloadMaxPinned ){
            String msg = "pinning the download max limit, due to downtick signal.";
            SpeedManagerLogger.trace(msg);
            SMSearchLogger.log(msg);
        }

        resetPinSearch();
    
public voidnotifyUpload(com.aelitis.azureus.core.speedmanager.SpeedManagerLimitEstimate estimate)

        int bestLimit = choseBestLimit(estimate,uploadLimitMax,uploadLimitConf);

        SpeedManagerLogger.trace("notifyUpload uploadLimitMax="+uploadLimitMax);
        tempLogEstimate(estimate);

        if(bestLimit!=uploadLimitMax){
            //update COConfiguration
            SpeedManagerLogger.log("persistent PingMap changed upload limit to "+bestLimit);

            resetPinSearch(estimate);

            uploadLimitMax = bestLimit;
            COConfigurationManager.setParameter(
                    SpeedManagerAlgorithmProviderV2.SETTING_UPLOAD_MAX_LIMIT, uploadLimitMax);
        }

        uploadLimitMin = SMConst.calculateMinUpload(uploadLimitMax);
        slider.updateLimits(uploadLimitMax,uploadLimitMin,downloadLimitMax,downloadLimitMin);

        SMSearchLogger.log("new upload rate: "+uploadLimitMax);
    
public SMUpdaterampTestingLimit(int uploadLimit, int downloadLimit)
Ramp the upload and download rates higher, so ping-times are relevant.

param
uploadLimit -
param
downloadLimit -
return
-

        SMUpdate retVal;
        if( transferMode.getMode() == TransferMode.State.DOWNLOAD_LIMIT_SEARCH
                && downloadBandwidthStatus.isGreater( SaturatedMode.MED ) )
        {
            downloadLimit *= 1.1f;
            clLastIncreaseTime = SystemTime.getCurrentTime();
            retVal = new SMUpdate(uploadLimit,false,downloadLimit,true);

        }else if( transferMode.getMode() == TransferMode.State.UPLOAD_LIMIT_SEARCH
                && uploadBandwidthStatus.isGreater( SaturatedMode.MED ))
        {
            uploadLimit *= 1.1f;
            clLastIncreaseTime = SystemTime.getCurrentTime();
            retVal = new SMUpdate(uploadLimit,true,downloadLimit,false);
            
        }else{
            retVal = new SMUpdate(uploadLimit,false,downloadLimit,false);
            SpeedManagerLogger.trace("ERROR: rampTestLimit should only be called during limit testing. ");
        }

        return retVal;
    
public voidreadFromPersistentMap()
replaces - updateFromCOConfigManager()

        //get persistent mapper.
        SpeedManager sm = AzureusCoreFactory.getSingleton().getSpeedManager();

        //get upload estimate.
        SpeedManagerLimitEstimate uEst = SMConst.filterEstimate(
                                            sm.getEstimatedUploadCapacityBytesPerSec(),
                                            SMConst.START_UPLOAD_RATE_MAX );

        int upPingMapLimit = uEst.getBytesPerSec();
        if(upPingMapLimit<SMConst.START_UPLOAD_RATE_MAX){
            //will find upload limit via slow search.
            uploadLimitMax = SMConst.START_UPLOAD_RATE_MAX;
        }else{
            uploadLimitMax = upPingMapLimit;
        }
        uploadLimitMin = SMConst.calculateMinUpload( uploadLimitMax );


        //get download estimate.
        SpeedManagerLimitEstimate dEst = SMConst.filterEstimate(
                                            sm.getEstimatedDownloadCapacityBytesPerSec(),
                                            SMConst.START_DOWNLOAD_RATE_MAX );


        int downPingMapLimit = dEst.getBytesPerSec();
        if( isSettingDownloadUnlimited() ){
            slider.setDownloadUnlimitedMode(true);
        }else{
            slider.setDownloadUnlimitedMode(false);
        }

        if(downPingMapLimit<SMConst.START_DOWNLOAD_RATE_MAX){
            downloadLimitMax = SMConst.START_DOWNLOAD_RATE_MAX;        
        }else{
            downloadLimitMax = downPingMapLimit;
        }
        downloadLimitMin = SMConst.calculateMinDownload( downloadLimitMax );

        uploadLimitConf = SpeedLimitConfidence.convertType( uEst.getEstimateType() );
        downloadLimitConf = SpeedLimitConfidence.convertType( dEst.getEstimateType() );

        percentUploadCapacityDownloadMode = (float)
                    COConfigurationManager.getIntParameter(SpeedLimitMonitor.USED_UPLOAD_CAPACITY_DOWNLOAD_MODE, 60)/100.0f;

        saveToCOConfiguration();
    
voidresetPinSearch()

        long currTime = SystemTime.getCurrentTime();

        uploadAtLimitStartTime = currTime;
        downloadAtLimitStartTime = currTime;
        isUploadMaxPinned = true;
        isDownloadMaxPinned = true;
    
voidresetPinSearch(com.aelitis.azureus.core.speedmanager.SpeedManagerLimitEstimate estimate)

        //chocking ping needs higher limit.
        float type = estimate.getEstimateType();
        if(type>=SpeedManagerLimitEstimate.TYPE_CHOKE_ESTIMATED){
            uploadChokePingCount++;
        }
        resetPinSearch();
    
public voidresetPingSpace()


        if( pingMapOfDownloadMode!=null && pingMapOfSeedingMode!=null){
            pingMapOfDownloadMode.reset();
            pingMapOfSeedingMode.reset();
        }
        
        if(transientPingMap!=null){
            transientPingMap.destroy();
        }
    
public voidsaveToCOConfiguration()

        COConfigurationManager.setParameter(SpeedManagerAlgorithmProviderV2.SETTING_UPLOAD_MAX_LIMIT,uploadLimitMax);
        COConfigurationManager.setParameter(SpeedManagerAlgorithmProviderV2.SETTING_DOWNLOAD_MAX_LIMIT,downloadLimitMax);
        COConfigurationManager.setParameter(SpeedLimitMonitor.UPLOAD_CONF_LIMIT_SETTING, uploadLimitConf.getString() );
        COConfigurationManager.setParameter(SpeedLimitMonitor.DOWNLOAD_CONF_LIMIT_SETTING, downloadLimitConf.getString() );
        COConfigurationManager.setParameter(SpeedLimitMonitor.UPLOAD_CHOKE_PING_COUNT,uploadChokePingCount);
    
public voidsetCurrentTransferRates(int downRate, int upRate)


        if( pingMapOfDownloadMode!=null && pingMapOfSeedingMode!=null){
            pingMapOfDownloadMode.setCurrentTransferRates(downRate,upRate);
            pingMapOfSeedingMode.setCurrentTransferRates(downRate,upRate);
        }

    
public voidsetDownloadBandwidthMode(int rate, int limit)

        downloadBandwidthStatus = SaturatedMode.getSaturatedMode(rate,limit);
    
public voidsetDownloadLimitSettingMode(int currLimit)

        downloadLimitSettingStatus = SaturatedMode.getSaturatedMode(currLimit, downloadLimitMax);
    
public voidsetRefLimits(com.aelitis.azureus.core.speedmanager.SpeedManagerLimitEstimate estUp, com.aelitis.azureus.core.speedmanager.SpeedManagerLimitEstimate estDown)
Make some choices about how usable the limits are before passing them on.

param
estUp -
param
estDown -


        SpeedManagerLimitEstimate up = SMConst.filterEstimate(estUp,SMConst.MIN_UPLOAD_BYTES_PER_SEC);
        int upMax = choseBestLimit(up, uploadLimitMax, uploadLimitConf);

        SpeedManagerLimitEstimate down = SMConst.filterEstimate(estDown, SMConst.MIN_DOWNLOAD_BYTES_PER_SEC);
        int downMax = choseBestLimit(down, downloadLimitMax, downloadLimitConf);

        if(downMax<upMax){
            SpeedManagerLogger.trace("down max-limit was less then up-max limit. increasing down max-limit. upMax="
                    +upMax+" downMax="+downMax);
            downMax = upMax;
        }

        setRefLimits(upMax,downMax);
    
public voidsetRefLimits(int uploadMax, int downloadMax)


        if( (uploadLimitMax!=uploadMax) && (uploadMax>0) ){
            uploadLimitMax=uploadMax;
            COConfigurationManager.setParameter(
                    SpeedManagerAlgorithmProviderV2.SETTING_UPLOAD_MAX_LIMIT, uploadLimitMax);
        }

        uploadLimitMin = SMConst.calculateMinUpload( uploadMax );

        if( (downloadLimitMax!=downloadMax) && (downloadMax>0) ){
            downloadLimitMax = downloadMax;
            COConfigurationManager.setParameter(
                    SpeedManagerAlgorithmProviderV2.SETTING_DOWNLOAD_MAX_LIMIT, downloadLimitMax);
        }

        downloadLimitMin = SMConst.calculateMinDownload(downloadMax);

        SpeedManagerLogger.trace("setRefLimits uploadMax="+uploadMax+" uploadLimitMax="+uploadLimitMax+", downloadMax="+downloadMax+" downloadLimitMax="+downloadLimitMax);

        slider.updateLimits(uploadLimitMax,uploadLimitMin,downloadLimitMax,downloadLimitMin);
    
public voidsetUploadBandwidthMode(int rate, int limit)

        uploadBandwidthStatus = SaturatedMode.getSaturatedMode(rate,limit);
    
public voidsetUploadLimitSettingMode(int currLimit)

        if( !transferMode.isDownloadMode() ){
            uploadLimitSettingStatus = SaturatedMode.getSaturatedMode(currLimit, uploadLimitMax);
        }else{
            uploadLimitSettingStatus = SaturatedMode.getSaturatedMode(currLimit, uploadLimitMax);
        }
    
public SMUpdatestartLimitTesting(int currUploadLimit, int currDownloadLimit)
Call this method to start the limit testing.

param
currUploadLimit -
param
currDownloadLimit -
return
- SMUpdate


        clLastIncreaseTime =SystemTime.getCurrentTime();
        clFirstBadPingTime =-1;

        highestUploadRate=0;
        highestDownloadRate=0;
        currTestDone=false;

        //reset the flag.
        beginLimitTest=false;

        //get the limits before the test, we are restoring them after the test.
        preTestUploadLimit = currUploadLimit;
        preTestDownloadLimit = currDownloadLimit;

        //configure the limits for this test. One will be at min and the other unlimited.
        SMUpdate retVal;
        if( transferMode.isDownloadMode() ){
            //test the download limit.
            retVal = new SMUpdate(uploadLimitMin,true,
                        Math.round(downloadLimitMax *1.2f),true);
            preTestDownloadCapacity = downloadLimitMax;
            transferMode.setMode( TransferMode.State.DOWNLOAD_LIMIT_SEARCH );
        }else{
            //test the upload limit.
            retVal = new SMUpdate( Math.round(uploadLimitMax *1.2f),true,
                        downloadLimitMin,true);
            preTestUploadCapacity = uploadLimitMax;
            transferMode.setMode( TransferMode.State.UPLOAD_LIMIT_SEARCH );
        }

        return retVal;
    
private voidtempLogEstimate(com.aelitis.azureus.core.speedmanager.SpeedManagerLimitEstimate est)


        if(est==null){
            SpeedManagerLogger.trace( "notify log: SpeedManagerLimitEstimate was null" );
        }

        StringBuffer sb = new StringBuffer();
        float metric = est.getMetricRating();
        float type = est.getEstimateType();
        int rate = est.getBytesPerSec();

        String str = est.getString();

        sb.append("notify log: ").append(str);
        sb.append(" metricRating=").append(metric);
        sb.append(" rate=").append(rate);
        sb.append(" type=").append(type);

        SpeedManagerLogger.trace( sb.toString() );

    
public voidtriggerLimitTestingFlag()

        SpeedManagerLogger.trace("triggerd fast limit test.");
        beginLimitTest=true;

        //if we are using a persistent PingSource then get that here.
        if( useVariancePingMap ){
            SMInstance pm = SMInstance.getInstance();
            SpeedManagerAlgorithmProviderAdapter adapter = pm.getAdapter();

            //start a new transientPingMap;
            if(transientPingMap!=null){
                transientPingMap.destroy();
            }
            transientPingMap = adapter.createTransientPingMapper();
        }

    
public voidupdateFromCOConfigManager()


        uploadLimitMax = COConfigurationManager.getIntParameter(SpeedManagerAlgorithmProviderV2.SETTING_UPLOAD_MAX_LIMIT);
        uploadLimitMin = SMConst.calculateMinUpload( uploadLimitMax );

        downloadLimitMax =COConfigurationManager.getIntParameter(SpeedManagerAlgorithmProviderV2.SETTING_DOWNLOAD_MAX_LIMIT);
        downloadLimitMin=SMConst.calculateMinDownload( downloadLimitMax );

        uploadLimitConf = SpeedLimitConfidence.parseString(
                COConfigurationManager.getStringParameter( SpeedLimitMonitor.UPLOAD_CONF_LIMIT_SETTING ));
        downloadLimitConf = SpeedLimitConfidence.parseString(
                COConfigurationManager.getStringParameter( SpeedLimitMonitor.DOWNLOAD_CONF_LIMIT_SETTING));

        percentUploadCapacityDownloadMode = (float)
                COConfigurationManager.getIntParameter(SpeedLimitMonitor.USED_UPLOAD_CAPACITY_DOWNLOAD_MODE, 60)/100.0f;

        uploadChokePingCount = Math.min(
                    COConfigurationManager.getIntParameter(SpeedLimitMonitor.UPLOAD_CHOKE_PING_COUNT),
                    30 );

        slider.updateLimits(uploadLimitMax,uploadLimitMin,downloadLimitMax,downloadLimitMin);
        slider.updateSeedSettings(percentUploadCapacityDownloadMode);


        if( isSettingDownloadUnlimited() ){
            slider.setDownloadUnlimitedMode( true );
        }

    
public synchronized voidupdateLimitTestingData(int downloadRate, int uploadRate)

param
downloadRate - currentUploadRate in bytes/sec
param
uploadRate - currentUploadRate in bytes/sec

        if( downloadRate>highestDownloadRate ){
            highestDownloadRate=downloadRate;
        }
        if( uploadRate>highestUploadRate){
            highestUploadRate=uploadRate;
        }

        //The exit criteria for this test is 30 seconds without an increase in the limits.
        long currTime = SystemTime.getCurrentTime();
        if( currTime > clLastIncreaseTime+CONF_LIMIT_TEST_LENGTH){
            //set the test done flag.
            currTestDone=true;
        }
        // or 30 seconds after its first bad ping.
        if( clFirstBadPingTime!=-1){
            if( currTime > clFirstBadPingTime+CONF_LIMIT_TEST_LENGTH){
                //set the test done flag.
                currTestDone=true;
            }
        }

    
public voidupdateLimitTestingPing(int lastMetric)
Convert raw ping value to new metric.

param
lastMetric -

        //Convert raw - pings into a rating.
        if(lastMetric>500){
            updateLimitTestingPing(-1.0f);
        }
    
public voidupdateLimitTestingPing(float lastMetric)
New metric from the PingMapper is value between -1.0 and +1.0f.

param
lastMetric -

        if( lastMetric<-0.3f){
            //Setting this time is a signal to end soon.
            clFirstBadPingTime = SystemTime.getCurrentTime();
        }
    
public voidupdateSettingsFromCOConfigManager()
Splitting the limits our from other setting for SpeedManagerAlgorithmTI.

        percentUploadCapacityDownloadMode = (float)
                COConfigurationManager.getIntParameter(SpeedLimitMonitor.USED_UPLOAD_CAPACITY_DOWNLOAD_MODE, 60)/100.0f;

        slider.updateSeedSettings(percentUploadCapacityDownloadMode);
    
public voidupdateTransferMode()

            
        transferMode.updateStatus( downloadBandwidthStatus );