SpeedManager.java
| Index Score | ||
|---|---|---|
![]() |
![]() |
org.furthurnet.datastructures.supporting |
![]() |
![]() |
Furthurnet |
View: Reasons, Metrics, Source Code
These are the metrics that contribute to the Enerjy Score for this file, ranked by impact. So the metrics listed at the top influence the score to a greater extent that the metrics listed at the bottom.
/*
* FURTHUR - A distributed peer-to-peer file sharing system.
* Copyright (C) 2001 Jamie M. Addessi
* jaddessi@pcpnetworks.com
*
* 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
*/
package org.furthurnet.datastructures.supporting;
import java.util.Vector;
import org.furthurnet.furi.ServiceManager;
public class SpeedManager // keeps track of client speed
{
private static final int RECORD_LENGTH = 50;
private static double[] SPEED_ESTIMATE = {-1, 5000, 1500, 300, 128, 56, 28, 0};
private static double oldIndex = 0.0;
private static boolean upstreamValidated = false;
private static Vector bandwidthUsers = new Vector();
public synchronized static void init(double _oldIndex)
{
oldIndex = Math.abs(_oldIndex);
upstreamValidated = (_oldIndex > 0);
}
public synchronized static boolean isUpstreamValidated()
{
return upstreamValidated;
}
public synchronized static void addBandwidthUser(BandwidthUser bu)
{
bandwidthUsers.add(bu);
}
public synchronized static void removeBandwidthUser(BandwidthUser bu)
{
bandwidthUsers.remove(bu);
}
public synchronized static double getCurrentIndex()
{
double currentUp = getCurrentTotalBandwidth(BandwidthUser.UPSTREAM);
double maxUp = ServiceManager.getCfg().mMaxUpstream;
if (currentUp > 0)
upstreamValidated = true;
if (!upstreamValidated)
return oldIndex;
else
{
double currentIndex = getIndex(currentUp);
if ((currentIndex > 0) && (currentIndex < oldIndex))
oldIndex = currentIndex;
if (maxUp > 0)
{
double throttleIndex = getIndex(maxUp);
if (throttleIndex > oldIndex)
oldIndex = throttleIndex;
}
return oldIndex;
}
/*
double upstreamTotal = 0.0;
int upstreamCount = 0;
double downstreamTotal = 0.0;
int downstreamCount = 0;
for (int i=0; i<bandwidthUsers.size(); i++)
{
try
{
double speed = ((BandwidthUser)bandwidthUsers.elementAt(i)).getPossibleSpeed();
if (speed > 0.0)
{
int type = ((BandwidthUser)bandwidthUsers.elementAt(i)).getBandwidthType();
if (type == BandwidthUser.DOWNSTREAM)
{
downstreamTotal += speed;
downstreamCount ++;
}
else if (type == BandwidthUser.UPSTREAM)
{
upstreamTotal += speed;
upstreamCount ++;
upstreamValidated = true;
}
}
}
catch (Exception e)
{}
}
double avgSpeed = 0.0;
if (upstreamCount > 0)
avgSpeed = upstreamTotal / upstreamCount; // assess speed index based on upstream speed
else if (upstreamValidated)
return oldIndex; // return the validated upstream speed if we have one
else if (downstreamCount > 0)
avgSpeed = projectUpstream(downstreamTotal / downstreamCount); // if no upstream data is available, project upstream based on downstream, giving the benefit of the doubt (he may be real fast, might as well find out)
else
return oldIndex; // no validated upstream, no data, use the old assessed value
double newIndex = Common.roundTo(getIndex(avgSpeed), 2);
if (upstreamValidated)
oldIndex = newIndex;
return oldIndex;*/
}
public synchronized static double getCurrentTotalBandwidth(int type)
{
double total = 0.0;
for (int i=0; i<bandwidthUsers.size(); i++)
{
try
{
if (type == ((BandwidthUser)bandwidthUsers.elementAt(i)).getBandwidthType())
total += ((BandwidthUser)bandwidthUsers.elementAt(i)).getActualSpeed();
}
catch (Exception e)
{}
}
return total;
}
private synchronized static double getSpeed(double index)
{
// translate the given kb/sec into an approximate PCP speed index. Doesn't really matter how,
// because it's used for RELATIVE node positioning. But should be consistent with
// "T-3 or greater" = 1
// "T-1" = 2
// "Cable Modem" = 3
// "DSL" = 4
// "56K or faster phone modem" = 5
// "Slower than 56K phone modem" = 6
// MUST be the inverse of the getIndex method.
if (index >= 7.0)
return 1.0;
else if (index <= 1.0)
return SPEED_ESTIMATE[1];
int category = getIndexCategory(index);
double offset = getOffset(index, (double)category, (double)(category + 1));
double speed = interpolate((1.0 - offset), getMinSpeed(category), getMaxSpeed(category));
if (speed <= 0.0)
return 1.0;
else if (speed > SPEED_ESTIMATE[1])
return SPEED_ESTIMATE[1];
else
return speed;
}
private synchronized static double getIndex(double speed)
{
// translate the given kb/sec into and approximate speed in kb/sec. MUST be the inverse
// of the above getSpeed method.
if (speed > SPEED_ESTIMATE[1])
return 1.0;
int category = getSpeedCategory(speed);
double offset = getOffset(speed, getMinSpeed(category), getMaxSpeed(category));
double index = interpolate((1.0 - offset), (double)category, (double)(category + 1));
return index;
}
private static int getIndexCategory(double index)
{
return (int)(Math.floor(index));
}
private static double getOffset(double d, double min, double max)
{
return (d - min) / (max - min);
}
private static double interpolate(double offset, double min, double max)
{
return min + offset * (max - min);
}
private static double getMinSpeed(int category)
{
return SPEED_ESTIMATE[category + 1];
}
private static double getMaxSpeed(int category)
{
return SPEED_ESTIMATE[category];
}
private static int getSpeedCategory(double speed)
{
for (int i=1; i<=6; i++)
if (speed > getMinSpeed(i))
return i;
return 6; // should never happen
}
private static double projectUpstream(double downstream)
{
// Predict upstream to be 80% af downstream. This is totally arbitrary, as it will be recalculated
// once the upstram is verified. However, it will give a decent approximation if the child enters
// another PCP transfer before the upstream is validated.
return downstream * 0.8;
}
}
The table below shows all metrics for SpeedManager.java.




