package com.limegroup.gnutella.statistics;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.limewire.core.settings.SearchSettings;
import org.limewire.inspection.InspectablePrimitive;
import com.google.inject.Singleton;
/** A default implementation of {@link OutOfBandStatistics} */
@Singleton
class OutOfBandStatisticsImpl implements OutOfBandStatistics {
private static final Log LOG = LogFactory.getLog(OutOfBandStatisticsImpl.class);
private static final int SAMPLE_SIZE = 500;
@InspectablePrimitive("oob sample size")
private AtomicInteger sampleSize = new AtomicInteger(SAMPLE_SIZE);
@InspectablePrimitive("oob requested")
private AtomicInteger requested = new AtomicInteger(0);
@InspectablePrimitive("oob received")
private AtomicInteger received = new AtomicInteger(0);
@InspectablePrimitive("oob bypassed")
private AtomicInteger bypassed = new AtomicInteger(0);
@InspectablePrimitive("oob sent")
private AtomicInteger sent = new AtomicInteger(0);
public void addBypassedResponse(int numBypassed) {
bypassed.addAndGet(numBypassed);
}
public void addReceivedResponse(int numReceived) {
received.addAndGet(numReceived);
}
public void addRequestedResponse(int numRequested) {
requested.addAndGet(numRequested);
}
public void addSentQuery() {
sent.incrementAndGet();
}
public int getRequestedResponses() {
return requested.get();
}
public int getSampleSize() {
return sampleSize.get();
}
public void increaseSampleSize() {
sampleSize.addAndGet(SAMPLE_SIZE);
}
public double getSuccessRate() {
double numRequested = requested.doubleValue();
double numReceived = received.doubleValue();
return (numReceived/numRequested) * 100;
}
public boolean isSuccessRateGood() {
// we want a large enough sample space.....
if (requested.get() < sampleSize.get()) {
LOG.debug("Assuming OOB success rate is good");
return true;
}
int threshold = SearchSettings.OOB_SUCCESS_RATE_GOOD.getValue();
boolean good = getSuccessRate() > threshold;
if(LOG.isDebugEnabled()) {
LOG.debug("OOB success rate of " +
getSuccessRate() + "% is " +
(good ? "" : "not ") + "good");
}
return good;
}
public boolean isSuccessRateGreat() {
// we want a large enough sample space.....
if (requested.get() < sampleSize.get()) {
LOG.debug("Assuming OOB success rate is great");
return true;
}
int threshold = SearchSettings.OOB_SUCCESS_RATE_GREAT.getValue();
boolean great = getSuccessRate() > threshold;
if(LOG.isDebugEnabled()) {
LOG.debug("OOB success rate of " +
getSuccessRate() + "% is " +
(great ? "" : "not ") + "great");
}
return great;
}
public boolean isSuccessRateTerrible() {
// we want a large enough sample space.....
if (requested.get() < sampleSize.get()) {
LOG.debug("Assuming OOB success rate is not terrible");
return false;
}
int threshold = SearchSettings.OOB_SUCCESS_RATE_TERRIBLE.getValue();
boolean terrible = getSuccessRate() < threshold;
if(LOG.isDebugEnabled()) {
LOG.debug("OOB success rate of " +
getSuccessRate() + "% is " +
(terrible ? "" : "not ") + "terrible");
}
return terrible;
}
public boolean isOOBEffectiveForProxy() {
if(SearchSettings.FORCE_OOB.getValue())
return true;
boolean effective = !((sent.get() > 40) && (requested.get() == 0));
if(LOG.isDebugEnabled()) {
LOG.debug("Sent " + sent.get() + " queries, requested " +
requested.get() + " responses, OOB is " +
(effective ? "" : "not ") + "effective for proxying");
}
return effective;
}
public boolean isOOBEffectiveForMe() {
if(SearchSettings.FORCE_OOB.getValue())
return true;
boolean effective = !((sent.get() > 20) && (requested.get() == 0));
if(LOG.isDebugEnabled()) {
LOG.debug("Sent " + sent.get() + " queries, requested " +
requested.get() + " responses, OOB is " +
(effective ? "" : "not ") + "effective for me");
}
return effective;
}
}