Hi,
Here are the patches that make this work.
Comments on devl still apply. With the defference that this does not use
the number of references to decide how much to favor a node getting a new
reference. Now it uses the sqrt(message success rate) to do this. This prevents
an attack where a 'baddy' sends lots of refs...
The stats it reports in the routing applet are much improved too.
Comments?
Ed
in node/rt
-----------------
--- CPAlgoRoutingTable.java 2003-06-19 09:31:20.000000000 -0400
+++ CPAlgoRoutingTable.java.new 2003-06-20 18:27:48.000000000 -0400
@@ -66,12 +66,23 @@
this.minDowntimeARKLookup = minDowntimeARKLookup;
this.minCP = minCP;
this.maxLookupThreads = maxLookupThreads;
+ this.cachedAttempts = 0;
+ this.cachedSuccesses = 0;
+ this.messageAttempts = 0;
+ this.messageSuccesses = 0;
+ this.globalEtime = 0l;
+ aFailed = 0;
+ aTimedOut = 0;
+ tFailed = 0;
}
int consecutiveFailuresLookupARK;
int minDowntimeARKLookup;
float minCP;
+ long globalEtime;
int maxLookupThreads;
+ int cachedAttempts, cachedSuccesses, messageAttempts, messageSuccesses;
+ int aFailed, aTimedOut, tFailed;
public RTDiagSnapshot getSnapshot() {
long nowMs = System.currentTimeMillis();
@@ -80,6 +91,7 @@
totalRefs = 0;
contactedRefs = 0;
requestingRefs = 0;
+ totalKeys = 0;
// ^^^ the fact that you have to do this suggests these
// should be local variables not instance variables -tc
@@ -111,6 +123,7 @@
}
ReferenceSet refSet = ReferenceSet.getProperty(memory, "keys");
+ totalKeys += refSet.size();
Enumeration refs = refSet.references();
while (refs.hasMoreElements()) {
if(shouldLog)
@@ -153,10 +166,19 @@
Object[] props = new Object[TABLE_PROPERTIES.length];
props[0] = new Integer(totalRefs);
props[1] = new Integer(contactedRefs);
- props[2] = new Integer(requestingRefs);
- props[3] = new Integer(totalAttempts);
- props[4] = new Integer(totalSuccesses);
- props[5] = getClass().getName();
+ props[2] = new Integer(totalKeys);
+ props[3] = new Integer(requestingRefs);
+ props[4] = new Integer(totalAttempts);
+ props[5] = new Integer(totalSuccesses);
+ props[6] = new Integer(cachedAttempts);
+ props[7] = new Integer(cachedSuccesses);
+ props[8] = new Integer(messageAttempts);
+ props[9] = new Integer(messageSuccesses);
+ props[10] = new Long(globalEtime);
+ props[11] = new Integer(aFailed);
+ props[12] = new Integer(aTimedOut);
+ props[13] = new Integer(tFailed);
+ props[14] = getClass().getName();
Key[] keyList = (Key[])keys.toArray(new Key[keys.size()]);
if(shouldLog)
@@ -195,21 +217,11 @@
}
}
-
- private final synchronized void incTrials(RoutingMemory mem) {
- CPAlgoData cpd = getProperty(mem, RMKEY, node);
- cpd.trials++;
- // We don't call mem.setProperty() because trials isn't
- // persisted.
- }
-
- private final synchronized void fail(RoutingMemory mem) {
- fail(mem, false);
- }
-
- private final synchronized void fail(RoutingMemory mem, boolean weak) {
+ private final synchronized void fail(RoutingMemory mem, float done, boolean
cached) {
CPAlgoData cpd = getProperty(mem, RMKEY, node);
- if (cpd.decreaseContactProbability(weak)) {
+ if (done == 1.0f)
+ cpd.increaseContactProbability(done);
+ else if (cpd.decreaseContactProbability(done)) {
remove(mem, null);
return;
}
@@ -221,52 +233,30 @@
remove((RoutingMemory)(routingStore.getNode(i)), i);
}
- private final synchronized void succeed(RoutingMemory mem, boolean cached,
- boolean attenuated, boolean weak) {
- CPAlgoData cpd = getProperty(mem, RMKEY, node);
- cpd.successes++;
- if (!cached) {
- // Uncached connections don't count.
- cpd.increaseContactProbability(weak);
- }
- mem.setProperty(RMKEY, cpd);
- }
-
- /**
- * Succeed and/or fail on weak or strong in a single step
- * @param strongSuccess whether we strongly (connection level) succeded
- * @param weakSuccess whether we weakly (query level) succeeded
- * @param ignoreStrong whether to leave the strong component unchanged
- * - generally set when we are dealing with a cached connection
+ /*
+ * Nodes set references to themselves when they want more
+ * traffic - lets take that into account. This should help
+ * conserve nodes with lots of keys, which should lead to
+ * better route selections.
*/
- protected final synchronized void succeedFail(RoutingMemory mem,
- boolean strongSuccess,
- boolean weakSuccess,
- boolean ignoreStrong) {
- CPAlgoData cpd = getProperty(mem, RMKEY, node);
- if(!ignoreStrong) {
- if(!strongSuccess) {
- if(cpd.decreaseContactProbability(false)) {
- remove(mem, null);
- return;
- }
- } else {
- cpd.increaseContactProbability(false);
+ public synchronized void reference(Key k, NodeReference nr) {
+ super.reference(k, nr);
+ RoutingMemory mem = routingStore.getNode(nr.getIdentity());
+ if (mem != null) {
+ ReferenceSet refSet = ReferenceSet.getProperty(mem, "keys");
+ CPAlgoData cpd = getProperty(mem, RMKEY, node);
+ if (refSet.size() > 1) {
+ cpd.perturbCP(refSet.size());
+ mem.setProperty(RMKEY, cpd);
+ Core.logger.log(this, "key reference perturbed CP",
+ Core.logger.DEBUG);
}
- }
- if(weakSuccess) {
- cpd.increaseContactProbability(true);
} else {
- if(cpd.decreaseContactProbability(true)) {
- remove(mem, null);
- return;
- }
+ Core.logger.log(this, "key reference found null mem",
+ Core.logger.DEBUG);
}
- if(weakSuccess || strongSuccess)
- cpd.successes++;
- mem.setProperty(RMKEY, cpd);
}
-
+
protected boolean isRoutable(RoutingMemory mem,
boolean desperate) {
return isRoutable(mem, desperate, "");
@@ -352,48 +342,133 @@
Logger.DEBUG);
}
}
-
+
+ // 33% done.
protected synchronized void routeConnected(RoutingMemory mem) {
- incTrials(mem);
- totalAttempts++;
+ synchronized(mem) {
+ CPAlgoData cpd = getProperty(mem, RMKEY, node);
+ cpd.trials++;
+ totalAttempts++;
+ cpd.state = 1;
+ }
}
+ // 66% done (routed at ip, auth ok)
protected synchronized void routeAccepted(RoutingMemory mem) {
- // hmm.. what?
+ synchronized(mem) {
+ CPAlgoData cpd = getProperty(mem, RMKEY, node);
+ if (cpd.state == 1) {
+ cpd.successes++;
+ totalSuccesses++;
+ cpd.state = 0;
+ }
+ }
}
+ // 100% done here
protected synchronized void routeSucceeded(RoutingMemory mem, boolean cached) {
- // Don't reward cached connections.
- succeedFail(mem, true, true, cached);
- totalSuccesses++;
+ synchronized(mem) {
+ CPAlgoData cpd = getProperty(mem, RMKEY, node);
+ if (!cached && cpd.state == 1) {
+ cpd.successes++;
+ totalSuccesses++;
+ cpd.state = 0;
+ }
+ cpd.cTrials++;
+ cpd.cSuccesses++;
+ cachedAttempts++;
+ cachedSuccesses++;
+ }
+ fail(mem,1.0f,cached);
}
+ // 0% done (did not get routeConnected)
protected synchronized void connectFailed(RoutingMemory mem) {
- incTrials(mem);
- totalAttempts++;
- fail(mem);
+ synchronized(mem) {
+ CPAlgoData cpd = getProperty(mem, RMKEY, node);
+ cpd.trials++;
+ totalAttempts++;
+ cpd.state = 0;
+ }
+ aFailed++;
+ fail(mem,0.0f,false);
}
+ // 0% done if this happens (have routeConnected but routeAccepted cannot occur)
protected synchronized void authFailed(RoutingMemory mem) {
- fail(mem);
+ synchronized(mem) {
+ CPAlgoData cpd = getProperty(mem, RMKEY, node);
+ cpd.state = 0;
+ }
+ fail(mem,0.0f,false);
// don't deref it completely in case this is corruption or something
- // don't ignore it because we want to clear out nodes that change identity
reasonably quickly
+ // don't ignrore it because we want to clear out nodes that change identity
reasonably quickly
}
+ // 5% done - seems only to be called during setup of the route. We give it 5%
since
+ // we did find something, but it was too busy to respond
protected synchronized void timedOut(RoutingMemory mem) {
- fail(mem);
+ synchronized(mem) {
+ CPAlgoData cpd = getProperty(mem, RMKEY, node);
+ if (cpd.state == 0) {
+ cpd.trials++;
+ totalAttempts++;
+ }
+ cpd.state = 0;
+ }
+ aTimedOut++;
+ fail(mem,minCP,false);
}
+ // 5% done - suspect this happens after routeSucceeded, no counts are affected.
This
+ // does not happen enought to really matter...
protected synchronized void transferFailed(RoutingMemory mem) {
- fail(mem);
+ synchronized(mem) {
+ CPAlgoData cpd = getProperty(mem, RMKEY, node);
+ cpd.state = 0;
+ }
+ tFailed++;
+ fail(mem,minCP,false);
}
- // this is not a tyop!
+ // this is not a tyop! No Fail call since we are removing the node...
protected synchronized void verityFailed(RoutingMemory mem) {
// dereference node
remove(mem, null);
}
+ // NGish routing
+ protected synchronized void searchFailed(RoutingMemory mem, Key k, long time, int
htl) {
+ synchronized(mem) {
+ CPAlgoData cpd = getProperty(mem, RMKEY, node);
+ cpd.mTrials++;
+ messageAttempts++;
+ }
+ }
+
+ // NGish routing
+ protected synchronized void messageFailed(RoutingMemory mem, Key k, long time,
int htl, long etime) {
+ synchronized(mem) {
+ CPAlgoData cpd = getProperty(mem, RMKEY, node);
+ cpd.mTrials++;
+ messageAttempts++;
+ }
+ }
+
+ // NGish routing
+ protected synchronized void messageSucceeded(RoutingMemory mem, Key k, long time,
int htl, long etime) {
+ synchronized(mem) {
+ CPAlgoData cpd = getProperty(mem, RMKEY, node);
+ cpd.mTrials++;
+ cpd.mSuccesses++;
+ messageAttempts++;
+ messageSuccesses++;
+ // use 0.1, later a kalman filter may make sense.
+ cpd.etime = cpd.etime + (etime - cpd.etime)/10l;
+ globalEtime = globalEtime + (etime - globalEtime)/10l;
+ }
+ }
+
private final synchronized boolean deleteReferences(ReferenceSet refSet,
long number) {
if(Core.logger.shouldLog(Core.logger.DEBUG))
@@ -424,6 +499,8 @@
// Reduce the chances of routing to nodes that always
// replies with QueryRejected.
protected synchronized void queryRejected(RoutingMemory mem, boolean cached, long
attenuation) {
+ float rp = 0.6f; // route success as measured
+ float cp = 0.75f; // connect success as measured
// I would have preferred to make queryRejected() in addition
// to routeSucceeded() to keep transport and application
@@ -432,9 +509,29 @@
// Counter-intutitive. The routing has succeeded at the
// transport layer, but we got a QueryRejected
// back at the application layer.
- //
- succeedFail(mem, true, false, cached);
- totalSuccesses++;
+
+ synchronized(mem) {
+ CPAlgoData cpd = getProperty(mem, RMKEY, node);
+ if (!cached && cpd.state == 1) {
+ cpd.successes++;
+ totalSuccesses++;
+ cpd.state = 0;
+ }
+ cpd.cTrials++;
+ cachedAttempts++;
+
+ // we bottom out at 0.01 since this is not a routing failure
+ if (cpd.trials > 0)
+ rp = java.lang.Math.max(((float) cpd.successes) / ((float)
cpd.trials), 0.01f);
+
+ if (cpd.cTrials > 0)
+ cp = java.lang.Math.max(((float) cpd.cSuccesses) / ((float)
cpd.cTrials), 0.01f);
+ }
+
+ if (cached)
+ fail(mem, cp, cached); // it was cached, next try probably will be too
+ else
+ fail(mem, rp*cp, cached); // we started from scratch probably will next
time
// Disable routing attenuation. 20020421 --gj
//
@@ -466,15 +563,18 @@
////////////////////////////////////////////////////////////
// Helper functions used to implement diagnostic snapshots.
private final static String[] REF_PROPERTIES
- = {"Address", "Contact Probability", "Consecutive Failures",
- "Connection Attempts", "Successful Connections",
+ = {"Address", "Contact Weight", "Successfull Routes",
+ "Successfull Connections", "Successfull Messages",
"Last Attempt", "NodeReference", "Node Version", "Key Count",
"ARK version", "Fetching ARK", "ARK URL"};
private final static String[] TABLE_PROPERTIES
- = {"Number of node references", "Contacted node references",
- "Node references requesting ARKs", "Total Trials",
- "Total Successes", "Implementation" };
+ = {"Number of node references", "Contacted node references", "Total Reference
Keys",
+ "Node references requesting ARKs",
+ "Route Trials", "Route Successes",
+ "Cached Trials", "Cached Successes",
+ "Message Trials", "Message Successes", "Successfull Messages etime",
+ "Route Failures", "TimedOut", "TransferFailed", "Implementation" };
// ^^^ i don't understand why you are doing this here
// instead of just passing the NodeReference back -tc
@@ -512,6 +612,7 @@
// Diagnostic stats set by makeRefInfo
private int totalRefs = 0;
private int requestingRefs = 0;
+ private int totalKeys = 0;
private int contactedRefs = 0;
private final Long LONG_MINUS_ONE = new Long(-1);
@@ -553,10 +654,9 @@
values[0] = ref.firstPhysicalToString();
// Don't phreak out cluebies with 0.0 cp during backoff.
values[1] = new Float(cpd.effectiveCP(nowMs));
- values[2] = new Long(cpd.consecutiveFailures);
- ///values[2] = new Integer(cpd.failureIntervals);
- values[3] = new Long(cpd.trials);
- values[4] = new Long(cpd.successes);
+ values[2] = new long[] {cpd.successes, cpd.trials};
+ values[3] = new long[] {cpd.cSuccesses, cpd.cTrials};
+ values[4] = new long[] {cpd.mSuccesses, cpd.mTrials, cpd.etime};
///values[5] = backedOffSecs(cpd, nowMs);
values[5] = lastAttemptSecs(cpd, nowMs, cpd.lastRetryMs);
values[6] = ref; // refs are immutable
@@ -565,7 +665,10 @@
ReferenceSet refSet = ReferenceSet.getProperty(mem, "keys");
values[8] = new Long(refSet.size());
values[9] = new Long(ref.revision());
- values[10] = new Boolean(cpd.fetchingARK());
+ if (cpd.fetchingARK())
+ values[10] = new Long(-cpd.consecutiveFailures);
+ else
+ values[10] = new Long(cpd.consecutiveFailures);
FreenetURI uri = ref.getARKURI(ref.revision());
if(uri != null)
values[11] = uri.toString(false);
@@ -654,12 +757,22 @@
**/
class CPAlgoData implements DataObject {
- // persisted.
- float contactProbability = 1.0f;
+ // persisted. Initial is rp=0.60 x cp=0.75 or about 0.45
+ private float contactProbability = 0.45f;
+
+ // better, but not foolproof timeout handling (0=initial, 1=routed)
+ int state = 0;
// Diagnostic info
long successes = 0;
long trials = 0;
+ long cSuccesses = 0;
+ long cTrials = 0;
+ long mSuccesses = 0;
+ long mTrials = 0;
+
+ // how fast does data flow from this node
+ long etime = 0l;
// Number of consecutive failures
long consecutiveFailures = 0;
@@ -760,55 +873,74 @@
final float contactProbability() {
if(contactProbability < minCP) {
- contactProbability = minCP;
- return minCP;
+ contactProbability = minCP;
+ return minCP;
}
return contactProbability;
}
-
+
+ final void perturbCP(int keys) {
+ float t = 0.0f;
+ if (mTrials > 0)
+ t = (float)mSuccesses/(float)mTrials;
+ // use the global message success rate (0.05) if we have not seen many
messages
+ if (mTrials < 20 && t < 0.05f)
+ t = 0.05f;
+ nextCP(1.0f, (float)java.lang.Math.sqrt(t));
+
+ }
+
+ final void nextCP(float value) {
+ nextCP(value, 0.1f);
+ }
+
+ // I tried a Kakman predictor here, but using k = 0.1 works as well...
+ final void nextCP(float value, float k) {
+ // r is measured noise variance
+ // q is plant noise variance
+ // in the limit k = sqrt(q/r) and p = sqrt(q*r)
+ // k = p/(p+r);
+ contactProbability = contactProbability + k*(value - contactProbability);
+ // p = (1-k)*p+q;
+ }
+
// returns true if the node should be dereferenced.
- final boolean decreaseContactProbability(boolean weak) {
- contactProbability =
- (float)(weak ? ((96.0 * contactProbability) / 100.0) :
- (((4.0 * contactProbability) /* + 0.0 */) / 5.0));
- // Decrease by 4% for weak, 20% for strong
- if(contactProbability < minCP) contactProbability = minCP;
- consecutiveFailures++;
- // When consecutiveFailures reaches some value, start an ARK lookup
- if(consecutiveFailures >= consecutiveFailuresLookupARK &&
- lastSuccessfulContact + minDowntimeARKLookup <
- System.currentTimeMillis()) {
- synchronized(lookupLock) {
- if(node == null) throw new IllegalStateException
+ final boolean decreaseContactProbability(float done) {
+ nextCP(done);
+ // When consecutiveFailures reaches some value, start an ARK lookup and
+ // its only a failure, in ARK terms, if the passed probability is zero.
+ if(done > 0f)
+ consecutiveFailures = 0;
+ else {
+ consecutiveFailures++;
+ if (consecutiveFailures >= consecutiveFailuresLookupARK &&
+ lastSuccessfulContact + minDowntimeARKLookup <
+ System.currentTimeMillis()) {
+ synchronized(lookupLock) {
+ if(node == null) throw new IllegalStateException
("creating LookupARK with null node");
- if(lookup == null && getARKURI() != null) {
- synchronized(lookupThreadsLock) {
- if(lookupThreads < maxLookupThreads)
- lookup = new LookupARK(getARKURI());
- }
+ if(lookup == null && getARKURI() != null) {
+ synchronized(lookupThreadsLock) {
+ if(lookupThreads < maxLookupThreads)
+ lookup = new LookupARK(getARKURI());
+ }
// FIXME: Kill the LookupARK whose ref is least recently used
+ }
}
- }
+ }
}
lastRetryMs = System.currentTimeMillis();
return false;
}
- final void increaseContactProbability(boolean weak) {
+ final void increaseContactProbability(float done) {
if(justFetchedARK) {
node.diagnostics.occurrenceCounting("successLookupARK",1);
justFetchedARK = false;
}
- if(contactProbability < minCP) contactProbability = minCP;
+ nextCP(done);
+ lastSuccessfulContact = lastRetryMs = System.currentTimeMillis();
consecutiveFailures = 0;
- float f = (float)
- (weak ? (((19 * contactProbability) + 1.0) / 20.0) :
- (((3.0 * contactProbability) + 1.0) / 4.0));
- // Move closer to 1.0 by 5% for weak
- // 25% for strong
- if(f>1) f = 1;
- contactProbability = f;
- lastRetryMs = lastSuccessfulContact = System.currentTimeMillis();
synchronized(lookupLock) {
if(lookup != null) {
lookup.kill();
@@ -816,7 +948,7 @@
}
}
}
-
+
final boolean fetchingARK() {
return lookup != null;
}
------------
--- Routing.java 2003-04-19 11:32:54.000000000 -0400
+++ Routing.java.new 2003-06-20 18:07:48.000000000 -0400
@@ -2,6 +2,7 @@
import freenet.Identity;
import freenet.node.NodeReference;
+import freenet.Key;
/**
* Supplies a sequence of NodeReferences in order of routing
@@ -101,6 +102,12 @@
* request is answered with a QueryRejected.
*/
void queryRejected(boolean cached, long attenuation);
+
+ void searchFailed(Key key, long time, int htl);
+
+ void messageFailed(Key key, long time, int htl, long etime);
+
+ void messageSucceeded(Key key, long time, int htl, long etime);
}
--------------------
--- TreeRouting.java 2003-06-19 09:31:20.000000000 -0400
+++ TreeRouting.java.new 2003-06-20 18:36:26.000000000 -0400
@@ -6,6 +6,7 @@
import freenet.support.BinaryTree.Node;
import freenet.support.MetricWalk;
import freenet.Core;
+import freenet.Key;
import java.util.Hashtable;
/**
@@ -221,6 +222,19 @@
public final void queryRejected(boolean cached, long attenuation) {
rt.queryRejected(mem, cached, attenuation);
}
+
+ public final void searchFailed(Key k, long time, int htl) {
+ rt.searchFailed(mem, k, time, htl);
+ }
+
+ public final void messageSucceeded(Key k, long time, int htl, long etime) {
+ rt.messageSucceeded(mem, k, time, htl, etime);
+ }
+
+ public final void messageFailed(Key k, long time, int htl, long etime) {
+ rt.messageFailed(mem, k, time, htl, etime);
+ }
+
}
------------
--- TreeRoutingTable.java 2003-05-16 21:28:02.000000000 -0400
+++ TreeRoutingTable.java.new 2003-06-20 18:08:35.000000000 -0400
@@ -259,6 +259,14 @@
protected abstract void verityFailed(RoutingMemory mem);
protected abstract void queryRejected(RoutingMemory mem, boolean cached, long
attenuation);
+
+ // then one of these per message (for NG Routing):
+
+ protected abstract void searchFailed(RoutingMemory mem, Key k, long time, int
htl);
+
+ protected abstract void messageSucceeded(RoutingMemory mem, Key k, long time, int
htl, long etime);
+
+ protected abstract void messageFailed(RoutingMemory mem, Key k, long time, int
htl, long etime);
}
--------------
in client/http
-------------
--- NodeStatusServlet.java 2003-06-05 21:08:37.000000000 -0400
+++ NodeStatusServlet.java.new 2003-06-20 18:12:20.000000000 -0400
@@ -1669,19 +1669,26 @@
}
if (rtType.equals("freenet.node.rt.CPAlgoRoutingTable")) {
- long attempts = ((Long)refValues[3]).longValue();
- long successful = ((Long)refValues[4]).longValue();
- if (attempts > 0 && successful > 0) {
- // percent successful
- refValues[4] = refValues[4].toString() + " ("
- + (long) (100 * successful / (double)attempts) + "%)";
- }
+ long attempts = ((long[])refValues[2])[1];
+ long successful = ((long[])refValues[2])[0];
+ refValues[2] = successful+ " / "
+ + attempts ;
+ attempts = ((long[])refValues[3])[1];
+ successful = ((long[])refValues[3])[0];
+ refValues[3] = successful+ " / "
+ + attempts ;
+
+ attempts = ((long[])refValues[4])[1];
+ successful = ((long[])refValues[4])[0];
+ long etime = ((long[])refValues[4])[2];
+ refValues[4] = successful+ " / "
+ + attempts +" : " + etime;
+
+ long failures = (long)((Long)refValues[10]).longValue();
boolean failing = true;
- if (refValues[2].equals(ZERO)) {
- refValues[2] = "none";
+ if (failures == 0)
failing = false;
- }
long ver = ((Long)refValues[9]).longValue();
NodeReference ref = (NodeReference)refValues[6];
@@ -1689,23 +1696,23 @@
String s = " <font color=\"";
String v = "";
- if (refValues[10].equals(TRUE))
+ if (failures < 0)
v = "blue"; // Fetching ARK
else if (failing)
v = "red"; // Failing
else if (!refValues[4].equals(ZERO))
v = "green"; // Working fine
- if(refValues[10].equals(TRUE)) {
+ if(failures < 0) {
if(ref.getARKURI(ver+1) == null) {
refValues[10] = "broken"; // it will fail soon enough
} else {
refValues[10] = "<a href=\"/"+
ref.getARKURI(ver+1).toString(false)+
- "\">yes</a>";
+ "\">yes</a> ("+(-failures)+")";
}
} else {
- refValues[10] = "no";
+ refValues[10] = "no ("+refValues[10].toString()+")";
}
// Black means not connected yet
--------------
and in node/states/request
-----------------
--- Pending.java 2003-06-19 09:31:20.000000000 -0400
+++ Pending.java.new 2003-06-20 18:51:31.000000000 -0400
@@ -731,6 +731,8 @@
long expectedTime = (replyTime - routedTime) +
(((endTransferTime - replyTime) * stdFileSize) /
receivingData.length());
+
+ routes.messageSucceeded(searchKey, replyTime-routedTime, hopsToLive,
expectedTime);
if(logDEBUG)
n.logger.log(this, "NGROUTING: Key "+searchKey+": search took "+
(replyTime-routedTime)+" in "+hopsToLive+", transfer took "+
@@ -763,6 +765,7 @@
public void logFailedTransfer(Node n, long endTime) {
if(loggedResult) return;
loggedResult = true;
+ routes.messageFailed(searchKey, replyTime-routedTime, hopsToLive, 0l);
if(logDEBUG)
n.logger.log(this, "NGROUTING: Key "+searchKey+": search took "+
(replyTime-routedTime)+" in "+hopsToLive+
@@ -774,6 +777,7 @@
public void logFailedSearch(Node n, long endTime) {
if(loggedResult) return;
loggedResult = true;
+ routes.searchFailed(searchKey, replyTime-routedTime, hopsToLive);
if(logDEBUG)
n.logger.log(this, "NGROUTING: Key "+searchKey+": search failed in "+
(endTime-routedTime)+" for "+hopsToLive+"; sent to "+
-------------
_______________________________________________
devl mailing list
[EMAIL PROTECTED]
http://hawk.freenetproject.org:8080/cgi-bin/mailman/listinfo/devl