package com.limegroup.gnutella.statistics;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.limegroup.gnutella.RouterService;
/**
* This class contains a type-safe enumeration of statistics for
* individual Gnutella messages that have been received from other
* nodes on the network. Each statistic maintains its own history,
* all messages received over a specific number of time intervals,
* etc. This class is specialized to only track messages received
* from LimeWires.
*/
public class OutOfBandThroughputStat extends BasicStatistic {
private static final Log LOG = LogFactory.getLog(OutOfBandThroughputStat.class);
public static int MIN_SAMPLE_SIZE = 500;
public static final int MIN_SUCCESS_RATE = 60;
public static final int PROXY_SUCCESS_RATE = 80;
public static final int TERRIBLE_SUCCESS_RATE = 40;
static {
Runnable adjuster = new Runnable() {
public void run() {
if (LOG.isDebugEnabled())
LOG.debug("current success rate "+ getSuccessRate()+
" based on "+((int)RESPONSES_REQUESTED.getTotal())+
" measurements with a min sample size "+MIN_SAMPLE_SIZE);
if (!isSuccessRateGreat() &&
!isSuccessRateTerrible()) {
LOG.debug("boosting sample size by 500");
MIN_SAMPLE_SIZE += 500;
}
}
};
int thirtyMins = 30 * 60 * 1000;
RouterService.schedule(adjuster, thirtyMins, thirtyMins);
}
/**
* Constructs a new <tt>MessageStat</tt> instance.
*/
private OutOfBandThroughputStat() {}
/**
* <tt>Statistic</tt> for Gnutella Hits requested over the UDP out-of-band
* protocol.
*/
public static final Statistic RESPONSES_REQUESTED =
new OutOfBandThroughputStat();
/**
* <tt>Statistic</tt> for Gnutella Hits requested over the UDP out-of-band
* protocol.
*/
public static final Statistic RESPONSES_RECEIVED =
new OutOfBandThroughputStat();
/**
* <tt>Statistic</tt> for number of Responses send via a ReplyNUmberVM but
* not retrieved.
*/
public static final Statistic RESPONSES_BYPASSED =
new OutOfBandThroughputStat();
/**
* <tt>Statistic</tt> for the number of OOB queries sent by this node.
*/
public static final Statistic OOB_QUERIES_SENT =
new OutOfBandThroughputStat();
/**
* @return a double from 0 to 100 that signifies the OOB success percentage.
*/
public static double getSuccessRate() {
double numRequested = RESPONSES_REQUESTED.getTotal();
double numReceived = RESPONSES_RECEIVED.getTotal();
return (numReceived/numRequested) * 100;
}
/**
* @return whether or not the success rate is good enough.
*/
public static boolean isSuccessRateGood() {
// we want a large enough sample space.....
if (RESPONSES_REQUESTED.getTotal() < MIN_SAMPLE_SIZE)
return true;
return (getSuccessRate() > MIN_SUCCESS_RATE);
}
/**
* @return whether or not the success rate is good enough for proxying.
*/
public static boolean isSuccessRateGreat() {
// we want a large enough sample space.....
if (RESPONSES_REQUESTED.getTotal() < MIN_SAMPLE_SIZE)
return true;
return (getSuccessRate() > PROXY_SUCCESS_RATE);
}
/**
* @return whether or not the success rate is terrible (less than 40%).
*/
public static boolean isSuccessRateTerrible() {
// we want a large enough sample space.....
if (RESPONSES_REQUESTED.getTotal() < MIN_SAMPLE_SIZE)
return false;
return (getSuccessRate() < TERRIBLE_SUCCESS_RATE);
}
/**
* @return A boolean if OOB queries have seemed ineffective, i.e. we've
* sent several but not received ANY results. Note that this is pessimistic
* and may shut off OOB even if it is working (i.e. if we've only done rare
* queries).
*/
public static boolean isOOBEffectiveForProxy() {
return !((OOB_QUERIES_SENT.getTotal() > 40) &&
(RESPONSES_REQUESTED.getTotal() == 0));
}
/**
* @return A boolean if OOB queries have seemed ineffective, i.e. we've
* sent several but not received ANY results. Note that this is pessimistic
* and may shut off OOB even if it is working (i.e. if we've only done rare
* queries).
*/
public static boolean isOOBEffectiveForMe() {
return !((OOB_QUERIES_SENT.getTotal() > 20) &&
(RESPONSES_REQUESTED.getTotal() == 0));
}
}