Update of /cvsroot/freenet/freenet/src/freenet/node/rt
In directory sc8-pr-cvs1:/tmp/cvs-serv7395/src/freenet/node/rt
Modified Files:
NodeEstimatorFactory.java NGRoutingTable.java
StandardNodeEstimator.java TimeEstimator.java
NodeEstimator.java TimeEstimatorFactory.java
StandardNodeEstimatorFactory.java
EstimatorFormatException.java DecayingRunningAverage.java
ResponseTimeEstimator.java
Added Files:
StandardNodeStats.java NodeStats.java
Log Message:
6348:
Pessimistic initial estimators. Break compatibility with previous Estimator fieldsets,
because they will have initially optimistic estimators. Combined with work in 6347, we
now have an initial implementation of what was planned on devl: pessimistic initial
estimators, and a means of ensuring that new nodes do get routed to despite it.
Fairly major supporting architectural work.
Minor bugfixes to graphs.
--- NEW FILE: StandardNodeStats.java ---
package freenet.node.rt;
/**
* Class contains stats on an NGRoutingTable
* @author amphibian
*/
public class StandardNodeStats implements NodeStats {
public double maxPConnectFailed;
public double maxPTransferFailed;
public double maxPSearchFailed;
public double maxPDNF;
public double minPDNF;
public double maxConnectFailTime;
public double maxConnectSuccessTime;
public double maxTransferFailedTime;
public double maxSearchFailedTime;
public double maxSuccessSearchTime;
public double maxDNFTime;
public double minTransferRate;
public String toString() {
return super.toString() +
"maxPConnectFailed="+maxPConnectFailed+
"maxPTransferFailed="+maxPTransferFailed+
"maxPSearchFailed="+maxPSearchFailed+
"maxPDNF="+maxPDNF+
"minPDNF="+minPDNF+
"maxConnectFailTime="+maxConnectFailTime+
"maxConnectSuccessTime="+maxConnectSuccessTime+
"maxTransferFailedTime="+maxTransferFailedTime+
"maxSearchFailedTime="+maxSearchFailedTime+
"maxSuccessSearchTime="+maxSuccessSearchTime+
"maxDNFTime="+maxDNFTime+
"minTransferRate="+minTransferRate;
}
/**
* Create an instance with pessimistic default values
*/
public static StandardNodeStats createPessimisticDefault() {
StandardNodeStats st = new StandardNodeStats();
st.maxPConnectFailed = 1.0;
st.maxPTransferFailed = 1.0;
st.maxPDNF = 1.0;
st.minPDNF = 0.99;
st.maxConnectFailTime = 1800*1000;
st.maxConnectSuccessTime = 1800*1000; // 30 mins
st.maxTransferFailedTime = 7200*1000; // 2 hours
st.maxSearchFailedTime = 600*1000; // 10 minutes
st.maxSuccessSearchTime = 600*1000;
st.maxDNFTime = 1800*1000;
st.minTransferRate = 1; // 1 byte per second
return st;
}
public StandardNodeStats() {
reset();
}
public void register(StandardNodeEstimator ne) {
double d = ne.pConnectFailed();
if(maxPConnectFailed < d)
maxPConnectFailed = d;
d = ne.pTransferFailed();
if(maxPTransferFailed < d)
maxPTransferFailed = d;
d = ne.pSearchFailed();
if(maxPSearchFailed < d)
maxPSearchFailed = d;
d = ne.pDNF();
if(maxPDNF < d)
maxPDNF = d;
if(minPDNF > d)
minPDNF = d;
d = ne.tConnectFailed();
if(maxConnectFailTime < d)
maxConnectFailTime = d;
d = ne.tConnectSucceeded();
if(maxConnectSuccessTime < d)
maxConnectSuccessTime = d;
d = ne.tSearchFailed();
if(maxSearchFailedTime < d)
maxSearchFailedTime = d;
d = ne.maxTSuccessSearch();
if(maxSuccessSearchTime < d)
maxSuccessSearchTime = d;
d = ne.maxDNFTime();
if(maxDNFTime < d)
maxDNFTime = d;
d = ne.minTransferRate();
if(minTransferRate > d)
minTransferRate = d;
}
public void reset() {
// Ridiculous values... if we get ANY hits, these should change
maxPConnectFailed = 0.0;
maxPTransferFailed = 0.0;
maxPDNF = 0.0;
maxConnectFailTime = 0;
maxConnectSuccessTime = 0;
maxTransferFailedTime = 0;
maxSearchFailedTime = 0;
maxSuccessSearchTime = 0;
maxDNFTime = 0;
minTransferRate = 1000.0*1000.0*1000.0*1000.0; // 1TB/sec!
}
public void register(NodeEstimator ne) {
if(ne instanceof StandardNodeEstimator)
register((StandardNodeEstimator)ne);
else
throw new IllegalArgumentException("Unrecognized estimator
type");
}
public double minPDNF() {
return minPDNF;
}
}
--- NEW FILE: NodeStats.java ---
package freenet.node.rt;
/**
* Interface for the stats that are passed when creating a new node.
* Used by NodeEstimatorFactory implementations to configure initial values.
* @author amphibian
*/
public interface NodeStats {
// Reset to default values (usually completely insane values - don't use it
until you've added some values)
void reset();
void register(NodeEstimator ne);
// Returns the minimum probability of a DNF
double minPDNF();
}
Index: NodeEstimatorFactory.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/node/rt/NodeEstimatorFactory.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -w -r1.6 -r1.7
--- NodeEstimatorFactory.java 13 Nov 2003 02:16:58 -0000 1.6
+++ NodeEstimatorFactory.java 22 Nov 2003 02:47:51 -0000 1.7
@@ -19,9 +19,8 @@
* @param estimator a FieldSet containing estimator data, or null
*/
NodeEstimator create(RoutingMemory mem,
- NodeReference ref, FieldSet
estimator, double rate,
- boolean needConnection, double
maxPDNF,
- long maxSearchTime, long maxDNFTime);
+ NodeReference ref, FieldSet
estimator,
+ boolean needConnection, NodeStats
stats);
NodeEstimator create(RoutingMemory mem, NodeReference ref,
DataObjectPending e,
boolean needConnection) throws
IOException;
@@ -30,10 +29,19 @@
* @param estimator a FieldSet containing estimator data, or null
*/
NodeEstimator create(RoutingMemory mem, NodeReference ref,
- FieldSet estimator, Key k, double
rate, boolean needConnection,
- double maxPDNF, long maxSearchTime,
- long maxDNFTime);
+ FieldSet estimator, Key k, boolean
needConnection,
+ NodeStats stats);
TimeEstimator createGlobalTimeEstimator();
/** Set the NGRoutingTable we are attached to */
void setNGRT(NGRoutingTable ngrt);
+ /**
+ * @return an instance of the NodeStats variant used to construct
+ * new node estimators in the absence of any specific data.
+ */
+ NodeStats createStats();
+ /**
+ * @return an instance of the NodeStats variant used by this class,
+ * initialized to the default values we use if we have zero RT data.
+ */
+ NodeStats defaultStats();
}
Index: NGRoutingTable.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/node/rt/NGRoutingTable.java,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -w -r1.46 -r1.47
--- NGRoutingTable.java 21 Nov 2003 21:12:43 -0000 1.46
+++ NGRoutingTable.java 22 Nov 2003 02:47:51 -0000 1.47
@@ -47,14 +47,11 @@
TimeEstimator globalEstimator;
public double fastestTransferSeen = 0;
public double defaultFastestTransferSeen;
- /**
- * Lowest overall probability of DNF on any node with nontrivial
- * successes.
- * 1.0 if there aren't any.
- */
- double pLegitDNF = 1.0;
- double pSemiLegitDNF = 1.0;
+ NodeStats newNodeStats = null;
+ NodeStats newNodeStatsLegit;
+ NodeStats newNodeStatsSemiLegit;
+ NodeStats defaultNodeStats;
// FIXME: should these be ints rather than longs? What about with alt transports?
/**
* Lowest max estimated search time of node estimators with nontrivial
@@ -87,6 +84,9 @@
this.timeFactory = tf;
factory.setNGRT(this);
this.defaultFastestTransferSeen = defaultFastestTransferSeen;
+ newNodeStatsLegit = factory.createStats();
+ newNodeStatsSemiLegit = factory.createStats();
+ defaultNodeStats = factory.defaultStats();
loadEstimators();
}
@@ -163,8 +163,7 @@
}
if(ne == null) {
ne = factory.create(mem, mem.getNodeReference(), null,
- getFastestRateSeen(), false, pLegitDNF,
- lowestEstimatedSearchTime, lowestEstimatedDNFTime);
+ false, defaultNodeStats);
}
mem.setProperty(NGKEY, ne);
estimators.put(ne.ref.getIdentity(), ne);
@@ -235,14 +234,13 @@
// New node, estimator centered on k
mem = routingStore.putNode(nr);
NodeEstimator e;
+ updateNewNodeStats();
if(k != null)
e = factory.create(mem, mem.getNodeReference(),
- estimator, k, getFastestRateSeen(), false, pLegitDNF,
- lowestEstimatedSearchTime, lowestEstimatedDNFTime);
+ estimator, k, false, newNodeStats);
else
e = factory.create(mem, mem.getNodeReference(),
- estimator, getFastestRateSeen(), false, pLegitDNF,
- lowestEstimatedSearchTime, lowestEstimatedDNFTime);
+ estimator, false, newNodeStats);
mem.setProperty(NGKEY, e);
estimators.put(e.ref.getIdentity(), e);
Core.diagnostics.occurrenceCounting("rtAddedNodes", 1);
@@ -284,19 +282,14 @@
//Recalculates the different DNF probabilities
- private synchronized void updateDNFProbabilities() {
+ private synchronized void updateNewNodeStats() {
//Vector v = new Vector(maxNodes);
Enumeration e = estimators.elements();
// FIXME!
- double pLegitDNF = 1.0F;
- double pSemiLegitDNF = 1.0F;
- long lowestLegitSearchTime = Long.MAX_VALUE;
- long lowestSemiLegitSearchTime = Long.MAX_VALUE;
- long lowestLegitDNFTime = Long.MAX_VALUE;
- long lowestSemiLegitDNFTime = Long.MAX_VALUE;
-
int nonWild = 0;
int semiWild = 0;
+ newNodeStatsLegit.reset();
+ newNodeStatsSemiLegit.reset();
while (e.hasMoreElements()) {
NodeEstimator ne = (NodeEstimator) (e.nextElement());
@@ -304,40 +297,28 @@
//retval.add(ne); Not returning vector anymore, if this check is
re-instated then we need to start returning a vector to the caller again
//else continue;
// Check connectability in NGRouting
- double d = ne.dnfProbability();
+ double d = ne.pDNF();
long searchTime = ne.highestEstimatedSearchTime();
long dnfTime = ne.highestDNFTime();
if (ne.successes() >= 1) {
semiWild++;
- pSemiLegitDNF = Math.min(pSemiLegitDNF,d);
- lowestSemiLegitSearchTime =
Math.min(lowestSemiLegitSearchTime,searchTime);
- lowestSemiLegitDNFTime = Math.min(lowestSemiLegitDNFTime,dnfTime);
+ newNodeStatsSemiLegit.register(ne);
}
if (ne.successes() > 5) {
nonWild++;
- if (node.connections.countConnections(ne.ref.getIdentity()) > 0)
- Core.logger.log(this, "New entry for pLegitDNF " + ne + " at " +
d, Logger.MINOR);
- pLegitDNF = Math.min(d, pLegitDNF);
- lowestLegitSearchTime = Math.min(lowestLegitSearchTime, searchTime);
- lowestLegitDNFTime = Math.min(lowestLegitDNFTime, searchTime);
+ newNodeStatsLegit.register(ne);
}
// FIXME!
}
if (nonWild < maxNodes / 4) {
if (semiWild > 0) {
- pLegitDNF = pSemiLegitDNF;
- lowestLegitSearchTime = lowestSemiLegitSearchTime;
- lowestLegitDNFTime = lowestSemiLegitDNFTime;
- }
- }
- if (lowestLegitSearchTime == Long.MAX_VALUE)
- lowestLegitSearchTime = defaultLowestSearchTime;
- if (lowestLegitDNFTime == Long.MAX_VALUE)
- lowestLegitDNFTime = defaultLowestEstimatedDNFTime;
- this.lowestEstimatedSearchTime = lowestLegitSearchTime;
- this.lowestEstimatedDNFTime = lowestLegitDNFTime;
- this.pLegitDNF = pLegitDNF;
- this.pSemiLegitDNF = pSemiLegitDNF;
+ newNodeStats = newNodeStatsSemiLegit;
+ } else
+ newNodeStats = defaultNodeStats;
+ } else
+ newNodeStats = newNodeStatsLegit;
+ Core.logger.log(this, "newNodeStats now: "+newNodeStats+
+ "(nonWild="+nonWild+", semiWild="+semiWild+")", Logger.DEBUG);
}
@@ -345,7 +326,7 @@
boolean force,
boolean isInsert,
boolean
orderByInexperience) {
- updateDNFProbabilities();
+ updateNewNodeStats();
Vector v = new Vector(maxNodes);
Enumeration e;
synchronized(this){
@@ -364,7 +345,7 @@
if(orderByInexperience) {
es = new Estimate(ne, ne.routeAccesses(), -1, -1);
} else {
- es = ne.longEstimate(k, htl, size, global, pLegitDNF);
+ es = ne.longEstimate(k, htl, size, global, newNodeStats.minPDNF());
}
estimates[i] = es;
i++;
@@ -393,7 +374,7 @@
else stdFileSize = 131072;
Key k = new Key(Key.halfkeyspace);
double global = globalEstimator.guessTime(k);
- updateDNFProbabilities();
+ updateNewNodeStats();
synchronized(this) {
Enumeration elements = estimators.elements();
while(elements.hasMoreElements()) {
@@ -424,7 +405,7 @@
totalConnectSuccesses += connectSuccesses;
refInfos.add(e.getDiagProperties(k, Node.maxHopsToLive,
- stdFileSize, global, pLegitDNF));
+ stdFileSize, global, newNodeStats.minPDNF()));
}
}
NodeReference[] realRefs = new NodeReference[nodeRefs.size()];
@@ -437,8 +418,8 @@
props[4] = new Integer(backedOffNodes);
props[5] = new Long(totalConnectAttempts);
props[6] = new Long(totalConnectSuccesses);
- props[7] = new Float(pLegitDNF);
- props[8] = new Float(pSemiLegitDNF);
+ props[7] = new Float(newNodeStatsLegit.minPDNF());
+ props[8] = new Float(newNodeStatsSemiLegit.minPDNF());
props[9] = Long.toString(lowestEstimatedSearchTime)+"ms";
props[10] = Long.toString(lowestEstimatedDNFTime)+"ms";
@@ -573,17 +554,8 @@
protected final Comparable getDiscardValue(RoutingMemory mem) {
NodeEstimator ne;
MyDiscardValue ret;
- try {
- ne = (NodeEstimator) mem.getProperty(NGKEY);
- } catch (DataObjectUnloadedException e) {
- try {
- ne = factory.create(mem, mem.getNodeReference(), e, false);
- } catch (IOException ex) {
- Core.logger.log(this, "Caught "+ex+" deserializing "+mem,
- Logger.ERROR);
- ne = null;
- }
- if(ne != null) mem.setProperty(NGKEY, ne);
+ synchronized(this) {
+ ne = (NodeEstimator)estimators.get(mem.getIdentity());
}
if(ne != null) {
int x = 0;
@@ -640,7 +612,7 @@
* @return Returns the pLegitDNF.
*/
public double getPLegitDNF() {
- return pLegitDNF;
+ return newNodeStats.minPDNF();
}
public void drawGraphBMP(int width,int height,OutputStream o,Identity
highLightIdentity) throws IOException{
Index: StandardNodeEstimator.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/node/rt/StandardNodeEstimator.java,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -w -r1.48 -r1.49
--- StandardNodeEstimator.java 21 Nov 2003 21:12:43 -0000 1.48
+++ StandardNodeEstimator.java 22 Nov 2003 02:47:51 -0000 1.49
@@ -62,9 +62,48 @@
RandomSource random;
long lastPartialSuccessTime;
+ public double pConnectFailed() {
+ return rpConnectFailed.currentValue();
+ }
+
+ public double pTransferFailed() {
+ return rpTransferFailed.currentValue();
+ }
+
+ public double pSearchFailed() {
+ return rpSearchFailed.currentValue();
+ }
+
+ public double tConnectFailed() {
+ return (long)rtConnectFailed.currentValue();
+ }
+
+ public double tConnectSucceeded() {
+ return (long)rtConnected.currentValue();
+ }
+
+ public double tSearchFailed() {
+ return (long)rtSearchFailed.currentValue();
+ }
+
+ public double maxTSuccessSearch() {
+ return etSuccessSearch.convertFromRaw(
+ etSuccessSearch.highestRaw(), TimeEstimator.TIME);
+ }
+
+ public double maxDNFTime() {
+ return etDNF.convertFromRaw(
+ etDNF.highestRaw(), TimeEstimator.TIME);
+ }
+
+ public double minTransferRate() {
+ return etTransferRate.convertFromRaw(etTransferRate.lowestRaw(),
+ TimeEstimator.TRANSFER_RATE);
+ }
+
public FieldSet toFieldSet() {
FieldSet fs = new FieldSet();
- fs.put("Version", "1");
+ fs.put("Version", "2");
fs.put("rpConnectFailed", rpConnectFailed.toFieldSet());
fs.put("rpTransferFailed", rpTransferFailed.toFieldSet());
fs.put("rpSearchFailed", rpSearchFailed.toFieldSet());
@@ -108,16 +147,16 @@
rtSearchFailed = raf.create(dis);
Core.logger.log(this, "Serialized in all RunningAverage's",
Logger.DEBUG);
- etSuccessSearch =
rtef.create(dis,ResponseTimeEstimator.convertTime(1000000),ResponseTimeEstimator.convertTime(0));
//0 millisecond to ~20 minutes
+ etSuccessSearch =
rtef.create(dis,ResponseTimeEstimator.convertTime(2000000),ResponseTimeEstimator.convertTime(0));
//0 millisecond to ~20 minutes
Core.logger.log(this, "Serialized in etSuccessSearch",
Logger.DEBUG);
- etTransferRate =
rtef.create(dis,ResponseTimeEstimator.convertRate(10000.0),ResponseTimeEstimator.convertRate(0.001));
//0.001 byte/s to ~10 megabyte/s
+ etTransferRate =
rtef.create(dis,ResponseTimeEstimator.convertRate(10000.0),ResponseTimeEstimator.convertRate(1.0/16000.0));
//0.001 byte/s to ~10 megabyte/s
Core.logger.log(this, "Serialized in etTransferRate",
Logger.DEBUG);
epDNFGivenNotSearchFailed =
rtef.create(dis,ResponseTimeEstimator.convertProbability(1.0),ResponseTimeEstimator.convertProbability(0.0));
Core.logger.log(this, "Serialized in etDNF",
Logger.DEBUG);
- etDNF =
rtef.create(dis,ResponseTimeEstimator.convertTime(1000000),ResponseTimeEstimator.convertTime(0));
//0 millisecond to ~20 minutes
+ etDNF =
rtef.create(dis,ResponseTimeEstimator.convertTime(10000000),ResponseTimeEstimator.convertTime(0));
//0 millisecond to ~20 minutes
Core.logger.log(this, "Serialized in "+this,
Logger.MINOR);
successes = dis.readInt();
@@ -142,21 +181,20 @@
}
/**
- * Create one from scratch for a completely new node, using insanely
- * optimistic defaults
+ * Create one from scratch for a completely new node, using pessimistic
defaults
* @argument k the initial specialization
* @argument initTransferRate initial transfer rate in bytes per second
+ * @argument maxPConnectFailed the highest pConnectFailed from a currently
+ * contactable, respectable node
*/
public StandardNodeEstimator(NGRoutingTable ngrt, NodeReference ref,
RoutingMemory mem,
FieldSet e, RunningAverageFactory raf,
- TimeEstimatorFactory
rtef, Key k,
- double
initTransferRate,
- boolean
needConnection, double maxPDNF,
- long maxSearchTime,
long maxDNFTime, RandomSource rand) {
+ TimeEstimatorFactory
rtef, Key k, StandardNodeStats stats,
+ boolean
needConnection, RandomSource rand) {
if(Core.logger.shouldLog(Logger.MINOR, this))
Core.logger.log(this, "New node in routing table
(StandardNodeEstimator impl) for "+
- ref+" ("+ngrt+"), details:"+"mem = "+mem+",
key="+k+", initTransferRate="+
- initTransferRate+",
needConnection="+needConnection+", e="+e, Logger.MINOR);
+ ref+" ("+ngrt+"), details:"+"mem = "+mem+",
key="+k+", stats="+
+ stats+", needConnection="+needConnection+",
e="+e, Logger.MINOR);
this.random = rand;
if(rand == null) throw new NullPointerException();
this.ngrt = ngrt;
@@ -170,9 +208,15 @@
try {
String v = e.get("Version");
if(v == null) throw new EstimatorFormatException("no
Version");
+ try {
int version = Fields.hexToInt(v);
- if(version != 1)
- throw new
EstimatorFormatException("Unsupported version "+version);
+ if(version != 2)
+ throw new
EstimatorFormatException("Unsupported version "+version, false);
+ } catch (NumberFormatException ex) {
+ EstimatorFormatException ee = new
EstimatorFormatException("Odd version: "+v+" ("+ex+")");
+ ee.initCause(ex);
+ throw ee;
+ }
rpConnectFailed =
raf.create(e.getSet("rpConnectFailed"));
rpTransferFailed =
raf.create(e.getSet("rpTransferFailed"));
rpSearchFailed =
raf.create(e.getSet("rpSearchFailed"));
@@ -188,52 +232,50 @@
serialized = true;
} catch (EstimatorFormatException x) {
Core.logger.log(this, "Caught "+x+" reading "+ref+"
from FieldSet :(",
- x, Logger.NORMAL);
+ x, x.important ? Logger.NORMAL :
Logger.MINOR);
serialized = false;
}
}
if(!serialized) {
Core.logger.log(this, "Creating StandardNodeEstimator from
scratch",
Logger.MINOR);
- // Set all the failure probabilities to 0
- rpConnectFailed = raf.create(0);
- rpTransferFailed = raf.create(0);
- rpSearchFailed = raf.create(0);
- rpDNF = raf.create(0);
- // Set all the failure times to 0 too. It will learn soon
enough.
- rtConnectFailed = raf.create(0);
- rtConnected = raf.create(0);
- rtTransferFailed = raf.create(0);
- rtSearchFailed = raf.create(0);
+ // Reasonable pessimism
+ rpConnectFailed = raf.create(stats.maxPConnectFailed);
+ rpTransferFailed = raf.create(stats.maxPTransferFailed);
+ rpSearchFailed = raf.create(stats.maxPSearchFailed);
+ rpDNF = raf.create(stats.maxPDNF);
+ rtConnectFailed = raf.create(stats.maxConnectFailTime);
+ rtConnected = raf.create(stats.maxConnectSuccessTime);
+ rtTransferFailed = raf.create(stats.maxTransferFailedTime);
+ rtSearchFailed = raf.create(stats.maxSearchFailedTime);
// Now the RTEs
// Peak is pLegitDNF, trough is 0.0
-
if(k == null) {
Core.logger.log(this, "Creating node estimators from
"+k,
Logger.DEBUG);
- epDNFGivenNotSearchFailed =
- rtef.createZero();
- etSuccessSearch = rtef.createZero();
- etTransferRate =
rtef.createInitTransfer(initTransferRate/1000);
- etDNF = rtef.createZero();
+ epDNFGivenNotSearchFailed =
rtef.createProbability(stats.minPDNF);
+ etSuccessSearch =
rtef.createTime(stats.maxSuccessSearchTime);
+ Core.logger.log(this, "createInitTransfer("+
+ stats.minTransferRate/1000+")",
Logger.DEBUG);
+ etTransferRate =
rtef.createInitTransfer(stats.minTransferRate/1000);
+ etDNF = rtef.createTime(stats.maxDNFTime);
} else {
Core.logger.log(this, "Creating node estimators from
scratch",
Logger.DEBUG);
epDNFGivenNotSearchFailed =
- rtef.createProbability(k, 0.0, maxPDNF);
- etSuccessSearch = rtef.createTime(k, 0, maxSearchTime);
- etTransferRate = rtef.createTransfer(k,
initTransferRate/1000,
- initTransferRate/2000);
- // initTransferRate is expected to be ludicrously high
- etDNF = rtef.createTime(k, 0, maxDNFTime);
+ rtef.createProbability(k, 1.0, stats.maxPDNF);
+ etSuccessSearch = rtef.createTime(k,
2*stats.maxSuccessSearchTime,
+ stats.maxSuccessSearchTime);
+ etTransferRate = rtef.createTransfer(k,
stats.minTransferRate/1000,
+ stats.minTransferRate/2000);
+ etDNF = rtef.createTime(k, 2*stats.maxDNFTime,
stats.maxDNFTime);
}
}
this.needConnection = needConnection;
- lastAccessedTime = System.currentTimeMillis();
- createdTime = System.currentTimeMillis();
+ createdTime = lastAccessedTime = System.currentTimeMillis();
}
- public double dnfProbability() {
+ public double pDNF() {
return rpDNF.currentValue();
}
@@ -287,9 +329,8 @@
tSuccessSearch = etSuccessSearch.guessTime(k);
} else {
transferRate = etTransferRate.guessTransferRate(k);
- if(transferRate == 0.0)
- Core.logger.log(this, "Insane transfer rate:
"+transferRate+" on "+
- this, Logger.NORMAL);
+ if(transferRate < (1.0/16000.0)) // 1/16th byte/sec, the
resolution
+ transferRate = (1.0/16000.0);
tSuccessSearch = etSuccessSearch.guessTime(k);
double tSuccess = tSuccessSearch +
(((double)size) / transferRate);
@@ -311,7 +352,8 @@
e = (long)estimate;
}
lastEstimate = e;
- if(Math.abs(e) > 24L * 3600L * 1000L) {
+ if(Math.abs(e) > 31 * 24L * 3600L * 1000L) {
+ // Some of these will have the initial pessimistic estimators!
// It can be well below 0, because of new nodes with pDNF <<
pLegitDNF
Core.logger.log(this, "Unreasonable estimate: "+e+" for "+
this, Logger.NORMAL);
@@ -661,6 +703,8 @@
pw.println("<td>"+ageString(now -
lastAccessedTime)+"</td></tr>");
pw.println("<tr><td>Last success</td>");
pw.println("<td>"+ageString(now -
lastSuccessTime)+"</td></tr>");
+ pw.println("<tr><td>Routing hits</td>");
+ pw.println("<td>"+Long.toString(routeAccesses)+"</td></tr>");
pw.println("</table>");
pw.println("<h2>Keyspace estimates (compared to other
nodes)</h2>");
pw.println("<img src=\""+imagePrefix+"overlayedcomposite"+
Index: TimeEstimator.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/node/rt/TimeEstimator.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -w -r1.6 -r1.7
--- TimeEstimator.java 13 Nov 2003 02:16:58 -0000 1.6
+++ TimeEstimator.java 22 Nov 2003 02:47:51 -0000 1.7
@@ -23,7 +23,7 @@
public void reportTransferRate(Key k, double rate);
/** Returns a tool which can be used for generating HTML reports of this
estimator. */
public TimeEstimator.HTMLReportTool getHTMLReportingTool();
-
+ public double convertFromRaw(long x, int type);
public long lowestRaw();
public long highestRaw();
/** An interface which represents a tool that gives the user of the
Index: NodeEstimator.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/node/rt/NodeEstimator.java,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -w -r1.21 -r1.22
--- NodeEstimator.java 21 Nov 2003 21:12:43 -0000 1.21
+++ NodeEstimator.java 22 Nov 2003 02:47:51 -0000 1.22
@@ -63,7 +63,7 @@
* @return the probability of DataNotFound, overall
* Used for other things dnfProbability(k)
*/
- abstract public double dnfProbability();
+ abstract public double pDNF();
// Successful connection
abstract public void routeConnected(long time);
Index: TimeEstimatorFactory.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/node/rt/TimeEstimatorFactory.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -w -r1.5 -r1.6
--- TimeEstimatorFactory.java 13 Nov 2003 02:16:58 -0000 1.5
+++ TimeEstimatorFactory.java 22 Nov 2003 02:47:51 -0000 1.6
@@ -18,6 +18,7 @@
* @param low the low value. This will occur at the key itself.
*/
public TimeEstimator createTime(Key k, long lowest, long highest);
+ public TimeEstimator createTime(Key k, double lowest, double highest);
public TimeEstimator createTransfer(Key k, double slowest, double fastest);
/**
* Create a TimeEstimator from its network-serialized form.
@@ -26,4 +27,7 @@
*/
public TimeEstimator create(FieldSet set, int maxAllowedTime,int
minAllowedTime)
throws EstimatorFormatException;
+ public TimeEstimator createTime(long maxDNFTime);
+ public TimeEstimator createTime(double maxDNFTime);
+ public TimeEstimator createProbability(double d);
}
Index: StandardNodeEstimatorFactory.java
===================================================================
RCS file:
/cvsroot/freenet/freenet/src/freenet/node/rt/StandardNodeEstimatorFactory.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -w -r1.7 -r1.8
--- StandardNodeEstimatorFactory.java 13 Nov 2003 20:49:54 -0000 1.7
+++ StandardNodeEstimatorFactory.java 22 Nov 2003 02:47:51 -0000 1.8
@@ -44,12 +44,11 @@
}
public NodeEstimator create(RoutingMemory mem,
- NodeReference ref,
FieldSet e, double rate,
- boolean
needConnection, double maxPDNF,
- long maxSearchTime,
long maxDNFTime) {
+ NodeReference ref,
FieldSet e,
+ boolean
needConnection, StandardNodeStats stats) {
// Create completely new NodeEstimator for the identity
NodeEstimator ne = new StandardNodeEstimator(ngrt, ref, mem, e, raf, rtef,
null,
- rate,
needConnection, maxPDNF, maxSearchTime, maxDNFTime, rand);
+
stats, needConnection, rand);
if(Core.logger.shouldLog(Logger.DEBUG, this))
Core.logger.log(this, "Created new NodeEstimator from scratch: "+ne,
Logger.DEBUG);
return ne;
@@ -66,10 +65,10 @@
}
public NodeEstimator create(RoutingMemory mem, NodeReference ref,
- FieldSet e, Key k,
double rate, boolean needConnection, double maxPDNF,
- long maxSearchTime,
long maxDNFTime) {
- NodeEstimator ne = new StandardNodeEstimator(ngrt, ref, mem, e, raf,
rtef, k, rate,
-
needConnection, maxPDNF, maxSearchTime, maxDNFTime, rand);
+ FieldSet e, Key k,
boolean needConnection,
+ StandardNodeStats
stats) {
+ NodeEstimator ne = new StandardNodeEstimator(ngrt, ref, mem, e, raf,
rtef, k,
+
stats, needConnection, rand);
if(Core.logger.shouldLog(Logger.DEBUG, this))
Core.logger.log(this, "Created new NodeEstimator from scratch:
"+ne, Logger.DEBUG);
return ne;
@@ -78,4 +77,27 @@
public TimeEstimator createGlobalTimeEstimator() {
return rtef.createZero();
}
+
+ public NodeEstimator create(RoutingMemory mem, NodeReference ref, FieldSet
estimator, boolean needConnection, NodeStats stats) {
+ if(stats instanceof StandardNodeStats)
+ return create(mem, ref, estimator, needConnection,
(StandardNodeStats)stats);
+ else
+ throw new IllegalArgumentException("Unrecognized stats type");
+ }
+
+ public NodeEstimator create(RoutingMemory mem, NodeReference ref, FieldSet
estimator, Key k, boolean needConnection, NodeStats stats) {
+ if(stats == null) throw new NullPointerException();
+ if(stats instanceof StandardNodeStats)
+ return create(mem, ref, estimator, k, needConnection,
(StandardNodeStats)stats);
+ else
+ throw new IllegalArgumentException("Unrecognized stats type");
+ }
+
+ public NodeStats createStats() {
+ return new StandardNodeStats();
+ }
+
+ public NodeStats defaultStats() {
+ return StandardNodeStats.createPessimisticDefault();
+ }
}
Index: EstimatorFormatException.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/node/rt/EstimatorFormatException.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -w -r1.1 -r1.2
--- EstimatorFormatException.java 13 Nov 2003 02:16:58 -0000 1.1
+++ EstimatorFormatException.java 22 Nov 2003 02:47:51 -0000 1.2
@@ -10,6 +10,7 @@
*/
class EstimatorFormatException extends IOException {
+ boolean important = true;
/**
* Create an EstimatorFormatException
*/
@@ -21,6 +22,11 @@
* Create an EstimatorFormatException
* @param message detail message
*/
+ public EstimatorFormatException(String message, boolean important) {
+ super(message);
+ this.important = important;
+ }
+
public EstimatorFormatException(String message) {
super(message);
}
Index: DecayingRunningAverage.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/node/rt/DecayingRunningAverage.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -w -r1.10 -r1.11
--- DecayingRunningAverage.java 13 Nov 2003 02:16:58 -0000 1.10
+++ DecayingRunningAverage.java 22 Nov 2003 02:47:51 -0000 1.11
@@ -25,8 +25,7 @@
if(Double.isInfinite(currentVal) || Double.isNaN(currentVal)) {
throw new IOException("Invalid value serializing in: "+currentVal);
}
- // hack to correct data - to be removed. edt
- if(currentVal<0 || currentVal>(3600*1000)) {
+ if(currentVal<0 || currentVal>(2*3600*1000)) {
Core.logger.log(this, "reset "+currentVal,
new Exception("debug"),
Logger.NORMAL);
Index: ResponseTimeEstimator.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/node/rt/ResponseTimeEstimator.java,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -w -r1.39 -r1.40
--- ResponseTimeEstimator.java 13 Nov 2003 02:16:58 -0000 1.39
+++ ResponseTimeEstimator.java 22 Nov 2003 02:47:51 -0000 1.40
@@ -409,7 +409,7 @@
*/
public double guessTransferRate(Key k) {
int x = guess(k);
- double p = ((double)x) / (16*1000);
+ double p = ((double)x+1) / (16*1000);
//1/16th second resolution. Return in bytes per millisecond.
if(x <= 1) logMINOR("Guessed transfer rate very low!");
return p;
@@ -426,6 +426,17 @@
return x;
}
+ public static int convertTime(double millis) {
+ int x;
+ if(millis < 0)
+ throw new IllegalArgumentException("Negative time "+millis);
+ if(millis > Integer.MAX_VALUE) {
+ slogNORMAL("Very high reported time: "+millis);
+ x = Integer.MAX_VALUE;
+ } else x = (int)millis;
+ return x;
+ }
+
public void reportTime(Key k, long millis) {
int x = convertTime(millis);
report(k, x);
@@ -450,7 +461,8 @@
slogNORMAL("Really high transfer rate!: "+rate);
x = Integer.MAX_VALUE;
} else {
- x = (int)(rate * 16);
+ x = ((int)(rate * 16))-1;
+ if(x<0) x = 0;
}
return x;
}
@@ -534,6 +546,10 @@
return new ResponseTimeEstimator(k, convertTime(highest),
convertTime(lowest), accuracy);
}
+ public TimeEstimator createTime(Key k, double lowest, double highest) {
+ return new ResponseTimeEstimator(k, convertTime(highest),
convertTime(lowest), accuracy);
+ }
+
public TimeEstimator createTransfer(Key k, double slowest, double
fastest) {
return new ResponseTimeEstimator(k, convertRate(fastest),
convertRate(slowest), accuracy);
}
@@ -556,6 +572,27 @@
minAllowedValue);
return new ResponseTimeEstimator(rps);
}
+
+ /* (non-Javadoc)
+ * @see freenet.node.rt.TimeEstimatorFactory#createTime(long)
+ */
+ public TimeEstimator createTime(long t) {
+ return new ResponseTimeEstimator(convertTime(t), accuracy);
+ }
+
+ /* (non-Javadoc)
+ * @see freenet.node.rt.TimeEstimatorFactory#createTime(double)
+ */
+ public TimeEstimator createTime(double t) {
+ return new ResponseTimeEstimator(convertTime(t), accuracy);
+ }
+
+ /* (non-Javadoc)
+ * @see freenet.node.rt.TimeEstimatorFactory#createProbability(double)
+ */
+ public TimeEstimator createProbability(double d) {
+ return new ResponseTimeEstimator(convertProbability(d),
accuracy);
+ }
}
public static void main(String[] args) {
@@ -725,9 +762,6 @@
}
}
- protected class StandardHTMLReportTool implements TimeEstimator.HTMLReportTool
- {
-
public double convertFromRaw(long x, int type) {
if(type == TIME) return (double)x;
if(type == PROBABILITY) return intToProbability((int)x);
@@ -735,6 +769,13 @@
throw new IllegalArgumentException("unknown type");
}
+ protected class StandardHTMLReportTool implements TimeEstimator.HTMLReportTool
+ {
+
+ public double convertFromRaw(long x, int type) {
+ return ResponseTimeEstimator.this.convertFromRaw(x,type);
+ }
+
public void dumpHtml(java.io.PrintWriter pw) throws IOException {
pw.println("<table border=\"0\">");
store.dumpHtml(pw);
_______________________________________________
cvs mailing list
[EMAIL PROTECTED]
http://dodo.freenetproject.org/cgi-bin/mailman/listinfo/cvs