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)); } }