Update of /cvsroot/freenet/freenet/src/freenet/node/rt
In directory sc8-pr-cvs1:/tmp/cvs-serv4379/src/freenet/node/rt
Modified Files:
StandardNodeEstimator.java ResponseTimeEstimator.java
TimeEstimator.java FFTTimeEstimator.java NGRoutingTable.java
Log Message:
Moved some HTML generation support code from StandardNodeEsitmator into an inner class
in TimeEstimator/StandardNodeEstimator.
Moved the report history in StandardNodeEstimator into an static inner class
Index: StandardNodeEstimator.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/node/rt/StandardNodeEstimator.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -w -r1.11 -r1.12
--- StandardNodeEstimator.java 27 Oct 2003 15:06:06 -0000 1.11
+++ StandardNodeEstimator.java 29 Oct 2003 21:53:23 -0000 1.12
@@ -395,11 +395,12 @@
pw.println(graphName(i)+"<br>");
TimeEstimator te = getEstimator(i);
int et = estimatorType(i);
- pw.println("Minimum: "+te.formatFromRaw(te.lowestRaw(), et)+
+ TimeEstimator.HTMLReportTool reportTool =
te.getHTMLReportingTool();
+ pw.println("Minimum: "+reportTool.lowestString(et)+
"<br>");
- pw.println("Maximum: "+te.formatFromRaw(te.highestRaw(), et)+
+ pw.println("Maximum: "+reportTool.highestString(et)+
"<br>");
- te.dumpHtml(pw);
+ reportTool.dumpHtml(pw);
pw.println("With last 64 points:<br/>");
pw.println("<img src=\""+imagePrefix+graphName(i)+
"\" width=\"640\" height=\"480\"><br/>");
Index: ResponseTimeEstimator.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/node/rt/ResponseTimeEstimator.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -w -r1.12 -r1.13
--- ResponseTimeEstimator.java 28 Oct 2003 14:14:36 -0000 1.12
+++ ResponseTimeEstimator.java 29 Oct 2003 21:53:23 -0000 1.13
@@ -1,10 +1,14 @@
package freenet.node.rt;
import freenet.Key;
import freenet.Core;
+import freenet.node.rt.TimeEstimator.HTMLReportTool;
import freenet.support.Logger;
import freenet.support.DataObjectPending;
import freenet.support.graph.*;
import freenet.support.sort.*;
+
+import java.util.Enumeration;
+import java.util.Iterator;
import java.util.Random;
import java.math.BigInteger;
import java.math.BigDecimal;
@@ -33,13 +37,8 @@
int time[];
double sensitivity[];
- //I need to see these from subclass --zab
- protected static int RECENT_LENGTH = 64;
- protected BigInteger recentKeys[] = new BigInteger[RECENT_LENGTH];
- protected int recentTimes[] = new int[RECENT_LENGTH];
- protected int recentPtr = 0;
- protected int recentCount = 0; //TOTHINK: this could grow fast, may be better off
with long
protected static final double SENSITIVITY_MAX = 10.0;
+ protected RecentReports recent;
static final int KEYBYTES = 23,
TIMEBYTES = 4,
@@ -82,33 +81,11 @@
sensitivity[x] = i.readDouble();
}
try {
- recentPtr = i.readInt();
- if(recentPtr >= RECENT_LENGTH)
- throw new IOException("recentPtr too high");
- if(recentPtr < 0)
- throw new IOException("invalid negative recentPtr");
- recentCount = i.readInt();
- if(recentCount < 0)
- throw new IOException("invalid negative recentCount");
+ recent = new RecentReports(i);
} catch (IOException e) {
// Not fatal - probably upgrading
- recentCount = recentPtr = 0;
- }
- int x = 0;
- try {
- for(x = 0; x<recentTimes.length;x++) {
- recentTimes[x] = i.readInt();
- if(recentTimes[x] < 0) throw new IOException("negative value");
- byte[] b = new byte[KEYBYTES];
- i.readFully(b);
- recentKeys[x] = new BigInteger(1, b);
- if(recentKeys[x].signum() == -1) throw new IOException("negative key");
- if(recentKeys[x].compareTo(keyspace) == 1)
- throw new IOException("exceeded keyspace");
- }
- } catch (IOException ioe) {
- recentPtr = recentCount = 0;
}
+
logDEBUG = Core.logger.shouldLog(Logger.DEBUG,this);
}
@@ -132,28 +109,7 @@
// in case of zero padding
o.writeDouble(sensitivity[i]);
}
- o.writeInt(recentPtr);
- o.writeInt(recentCount);
- for(int i=0;i<recentTimes.length;i++) {
- o.writeInt(recentTimes[i]);
- byte[] b;
- if(recentKeys[i] == null) {
- b = new byte[KEYBYTES];
- for(int ii=0;ii<KEYBYTES;ii++) b[ii] = 0;
- } else {
- b = recentKeys[i].toByteArray();
- if(b.length > KEYBYTES + 1)
- throw new IllegalStateException("Key too long in serializing:
"+
- b.length);
- }
- if(b.length < KEYBYTES) {
- int skip = KEYBYTES - b.length;
- for(int x=0;x<skip;x++)
- o.writeByte(0);
- o.write(b);
- } else o.write(b, b.length - KEYBYTES, KEYBYTES);
- // in case of zero padding
- }
+ recent.writeTo(o);
}
}
@@ -485,12 +441,7 @@
BigInteger n = convert(k);
if(usec < 0) throw new IllegalArgumentException("negative usec in report()");
-
- recentKeys[recentPtr] = n;
- recentTimes[recentPtr] = usec;
- recentCount++;
- recentPtr++;
- if(recentPtr >= RECENT_LENGTH) recentPtr = 0;
+ recent.report(n,usec);
int pos = search(n);
@@ -552,34 +503,6 @@
// }
}
- public void dumpHtml(java.io.PrintWriter pw) throws IOException {
- pw.println("<table border=\"0\">");
- for(int x=0;x<key.length;x++) {
- pw.println("<tr><td>"+x+"</td><td>"+key[x].toString(16)+
- "</td><td>"+time[x]+"</td><td>"+sensitivity[x]+
- "</td></tr>");
- if(time[x] < 0)
- Core.logger.log(this, "time["+x+"]="+time[x]+
- " - NEGATIVE ("+this+")", Logger.ERROR);
- }
- pw.println("<tr><td>Maximum</td><td colspan=\"2\">"+
- keyspace.toString(16)+
- "</td></tr>");
- // I hope there is an optimized toString(16) ...
- pw.println("</table>");
-// if(recentCount > 0) {
-// pw.println("<p>Recent points</p>");
-// pw.println("<table border=\"0\">");
-// int l = recentPtr;
-// if(recentCount > RECENT_LENGTH) l = RECENT_LENGTH;
-// for(int i=0;i<l;i++) {
-// pw.println("<tr><td>"+i+"</td><td>"+recentKeys[i].toString(16)+
-// "</td><td>"+recentTimes[i]+"</td></tr>");
-// }
-// pw.println("</table>");
-// }
- }
-
public void dumpLog() {
if (Core.logger.shouldLog(Logger.MINOR, this)) {
StringBuffer sb = new StringBuffer();
@@ -682,44 +605,6 @@
return (long)guess(k);
}
- public long highestRaw() {
- int highest = 0;
- for(int x=0;x<time.length;x++) {
- if(time[x] > highest) highest = time[x];
- }
- return highest;
- }
-
- public long lowestRaw() {
- int lowest = Integer.MAX_VALUE;
- for(int x=0;x<time.length;x++) {
- if(time[x] < lowest) lowest = time[x];
- }
- return lowest;
- }
-
- public double convertFromRaw(long x, int type) {
- if(type == TIME) return (double)x;
- if(type == PROBABILITY) return intToProbability((int)x);
- if(type == TRANSFER_RATE) return ((double)x) / (16*1000);
- throw new IllegalArgumentException("unknown type");
- }
-
- public String formatFromRaw(long x, int type) {
- if(x < 0) {
- dumpLog();
- throw new IllegalArgumentException("negative!");
- }
- if(type == TIME) return Long.toString(x)+"ms";
- if(type == PROBABILITY) {
- if(x > Integer.MAX_VALUE) throw new IllegalArgumentException("to big
probability");
- return Double.toString(intToProbability((int)x));
- }
- if(type == TRANSFER_RATE)
- return Double.toString(((double)x) / (16*1000)) + "bytes/second";
- throw new IllegalArgumentException("unknown type");
- }
-
public int guess(Key k) {
return guess(convert(k));
}
@@ -863,6 +748,206 @@
}*/
}
+ /* (non-Javadoc)
+ * @see freenet.node.rt.TimeEstimator#getReport()
+ */
+ public HTMLReportTool getHTMLReportingTool() {
+ return new StandardHTMLReportTool();
+ }
+
+ public long highestRaw() {
+ int highest = 0;
+ for(int x=0;x<time.length;x++) {
+ if(time[x] > highest) highest = time[x];
+ }
+ return highest;
+ }
+
+ public long lowestRaw() {
+ int lowest = Integer.MAX_VALUE;
+ for(int x=0;x<time.length;x++) {
+ if(time[x] < lowest) lowest = time[x];
+ }
+ return lowest;
+ }
+ //A class for keeping track of the recent reports that has come in to the
Estimator
+ protected static class RecentReports {
+ // I need to see these from subclass --zab
+ protected static int RECENT_LENGTH = 64;
+ protected BigInteger recentKeys[] = new BigInteger[RECENT_LENGTH];
+ protected int recentTimes[] = new int[RECENT_LENGTH];
+ protected int recentPtr = 0;
+ protected int recentCount = 0; //TOTHINK: this could grow fast, may be
better off with long
+ public RecentReports(DataInputStream i) throws IOException {
+ try {
+ recentPtr = i.readInt();
+ if (recentPtr >= RECENT_LENGTH)
+ throw new IOException("recentPtr too high");
+ if (recentPtr < 0)
+ throw new IOException("invalid negative
recentPtr");
+ recentCount = i.readInt();
+ if (recentCount < 0)
+ throw new IOException("invalid negative
recentCount");
+ int x = 0;
+
+ for (x = 0; x < recentTimes.length; x++) {
+ recentTimes[x] = i.readInt();
+ if (recentTimes[x] < 0)
+ throw new IOException("negative
value");
+ byte[] b = new byte[KEYBYTES];
+ i.readFully(b);
+ recentKeys[x] = new BigInteger(1, b);
+ if (recentKeys[x].signum() == -1)
+ throw new IOException("negative key");
+ if (recentKeys[x].compareTo(keyspace) == 1)
+ throw new IOException("exceeded
keyspace");
+ }
+ } catch (IOException ioe) {
+ //Sane initial values in case someone wants to use us
+ //even though the reading above failed
+ recentPtr = recentCount = 0;
+ throw ioe;
+ }
+ }
+ void report(BigInteger n, int usec) {
+ recentKeys[recentPtr] = n;
+ recentTimes[recentPtr] = usec;
+ recentCount++;
+ recentPtr++;
+ if (recentPtr >= RECENT_LENGTH)
+ recentPtr = 0;
+ }
+ LowestHighestPair getLowestAndHighest(boolean dontClipPoints) {
+ LowestHighestPair l = new LowestHighestPair();
+ int x = recentPtr;
+ if (recentCount > RECENT_LENGTH)
+ x = RECENT_LENGTH;
+ if (dontClipPoints) {
+ for (int i = 0; i < x; i++) {
+ if (recentTimes[i] < l.lowest)
+ l.lowest = recentTimes[i];
+ if (recentTimes[i] > l.highest)
+ l.highest = recentTimes[i];
+ }
+ }
+ return l;
+ }
+
+ public void writeTo(DataOutputStream o) throws IOException {
+ o.writeInt(recentPtr);
+ o.writeInt(recentCount);
+ for (int i = 0; i < recentTimes.length; i++) {
+ o.writeInt(recentTimes[i]);
+ byte[] b;
+ if (recentKeys[i] == null) {
+ b = new byte[KEYBYTES];
+ for (int ii = 0; ii < KEYBYTES; ii++)
+ b[ii] = 0;
+ } else {
+ b = recentKeys[i].toByteArray();
+ if (b.length > KEYBYTES + 1)
+ throw new IllegalStateException("Key
too long in serializing: " + b.length);
+ }
+ if (b.length < KEYBYTES) {
+ int skip = KEYBYTES - b.length;
+ for (int x = 0; x < skip; x++)
+ o.writeByte(0);
+ o.write(b);
+ } else
+ o.write(b, b.length - KEYBYTES, KEYBYTES);
+ // in case of zero padding
+ }
+ }
+ Enumeration enumeration()
+ {
+ return new RecentEnumeration();
+ }
+ class LowestHighestPair {
+ int lowest = Integer.MAX_VALUE;
+ int highest = 0;
+ }
+ class KeyTimePair{
+ BigInteger key;
+ int time;
+ public KeyTimePair(BigInteger key, int time) {
+ this.key = key;
+ this.time = time;
+ }
+ }
+ class RecentEnumeration implements Enumeration{
+ int location =0;
+
+ /* (non-Javadoc)
+ * @see java.util.Enumeration#hasMoreElements()
+ */
+ public boolean hasMoreElements() {
+ return location < RECENT_LENGTH;
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.Enumeration#nextElement()
+ */
+ public Object nextElement() {
+ location++;
+ return new
KeyTimePair(recentKeys[location-1],recentTimes[location-1]);
+ }
+
+ }
+ }
+
+ 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);
+ if(type == TRANSFER_RATE) return ((double)x) / (16*1000);
+ throw new IllegalArgumentException("unknown type");
+ }
+
+ public void dumpHtml(java.io.PrintWriter pw) throws IOException {
+ pw.println("<table border=\"0\">");
+ for(int x=0;x<key.length;x++) {
+ pw.println("<tr><td>"+x+"</td><td>"+key[x].toString(16)+
+ "</td><td>"+time[x]+"</td><td>"+sensitivity[x]+
+ "</td></tr>");
+ if(time[x] < 0)
+ Core.logger.log(this, "time["+x+"]="+time[x]+
+ " - NEGATIVE ("+this+")",
Logger.ERROR);
+ }
+ pw.println("<tr><td>Maximum</td><td colspan=\"2\">"+
+ keyspace.toString(16)+
+ "</td></tr>");
+ // I hope there is an optimized toString(16) ...
+ pw.println("</table>");
+ // if(recentCount > 0) {
+ // pw.println("<p>Recent points</p>");
+ // pw.println("<table border=\"0\">");
+ // int l = recentPtr;
+ // if(recentCount > RECENT_LENGTH) l = RECENT_LENGTH;
+ // for(int i=0;i<l;i++) {
+ //
pw.println("<tr><td>"+i+"</td><td>"+recentKeys[i].toString(16)+
+ // "</td><td>"+recentTimes[i]+"</td></tr>");
+ // }
+ // pw.println("</table>");
+ // }
+ }
+
+ public String formatFromRaw(long x, int type) {
+ if(x < 0) {
+ dumpLog();
+ throw new IllegalArgumentException("negative!");
+ }
+ if(type == TIME) return Long.toString(x)+"ms";
+ if(type == PROBABILITY) {
+ if(x > Integer.MAX_VALUE) throw new
IllegalArgumentException("to big probability");
+ return Double.toString(intToProbability((int)x));
+ }
+ if(type == TRANSFER_RATE)
+ return Double.toString(((double)x) / (16*1000)) +
"bytes/second";
+ throw new IllegalArgumentException("unknown type");
+ }
+
public void drawGraphBMP(int width, int height, boolean dontClipPoints,
OutputStream os)
throws IOException {
@@ -876,18 +961,14 @@
val[i] = guess(at);
// Core.logger.log(this, "Guess for "+at+": "+val[i],
// Logger.DEBUG);
- if(val[i] < lowest) lowest = val[i];
- if(val[i] > highest) highest = val[i];
+ lowest = Math.min(lowest,val[i]);
+ highest = Math.max(highest,val[i]);
at = at.add(b);
}
- int x = recentPtr;
- if(recentCount > RECENT_LENGTH) x = RECENT_LENGTH;
- if(dontClipPoints) {
- for(int i=0;i<x;i++) {
- if(recentTimes[i] < lowest) lowest = recentTimes[i];
- if(recentTimes[i] > highest) highest = recentTimes[i];
- }
- }
+ RecentReports.LowestHighestPair lowestAndHighestRecent =
recent.getLowestAndHighest(dontClipPoints);
+ lowest = Math.min(lowestAndHighestRecent.lowest,lowest);
+ highest = Math.max(lowestAndHighestRecent.highest,highest);
+
// lowest ... highest
// lowest mapped to 0
// highest mapped to height
@@ -901,17 +982,39 @@
}
// Now plot the recent points
bmp.setPenColor(new Color(255,0,0));
- for(int i=0;i<x;i++) {
- int w = recentKeys[i].divide(b).intValue();
- int h = (int)((recentTimes[i] - lowest) * multiplier);
- if(h < 0) h = 0;
- if(h > height-1) h = height-1;
+ Enumeration e = recent.enumeration();
+ while(e.hasMoreElements())
+ {
+ RecentReports.KeyTimePair kt =
(RecentReports.KeyTimePair)e.nextElement();
+ int w = kt.key.divide(b).intValue();
+ int h = (int)((kt.time - lowest) * multiplier);
+ h = Math.max(h,0);
+ h = Math.min(height-1,h);
h = height - (h+1);
bmp.drawPlus(w,h);
}
+
BitmapEncoder enc = new DibEncoder();
enc.setBitmap(bmp);
enc.encode(os);
os.close();
}
+
+ /* (non-Javadoc)
+ * @see freenet.node.rt.TimeEstimator.HTMLReportTool#lowestString()
+ */
+ public String lowestString(int type) {
+ return formatFromRaw(lowestRaw(),type);
+ }
+
+ /* (non-Javadoc)
+ * @see freenet.node.rt.TimeEstimator.HTMLReportTool#highestString()
+ */
+ public String highestString(int type) {
+ return formatFromRaw(highestRaw(),type);
+ }
+
+
+ }
+
}
Index: TimeEstimator.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/node/rt/TimeEstimator.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -w -r1.2 -r1.3
--- TimeEstimator.java 30 Aug 2003 23:16:52 -0000 1.2
+++ TimeEstimator.java 29 Oct 2003 21:53:23 -0000 1.3
@@ -5,13 +5,9 @@
public interface TimeEstimator extends DataObject {
public long guessRaw(Key k);
- public long lowestRaw();
- public long highestRaw();
public static final int TIME = 0;
public static final int PROBABILITY = 1;
public static final int TRANSFER_RATE = 2;
- public double convertFromRaw(long x, int type);
- public String formatFromRaw(long x, int type);
/** Return the guessed time for the given key, in milliseconds */
public double guessTime(Key k);
/** Return the guessed probability for the given key */
@@ -22,8 +18,22 @@
public void reportProbability(Key k, double p);
/** Report transfer rate in bytes per millisecond. */
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 long lowestRaw();
+ public long highestRaw();
+ /** An interface which represents a tool that gives th user of the
+ * TimeEstimator some help with rendering the estimator to HTML */
+ interface HTMLReportTool
+ {
+ public String lowestString(int type);
+ public String highestString(int type);
+ public double convertFromRaw(long x, int type);
+ public String formatFromRaw(long x, int type);
public void drawGraphBMP(int width, int height, boolean dontClipPoints,
java.io.OutputStream os)
throws java.io.IOException;
public void dumpHtml(java.io.PrintWriter pw) throws java.io.IOException;
+ }
}
Index: FFTTimeEstimator.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/node/rt/FFTTimeEstimator.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -w -r1.2 -r1.3
--- FFTTimeEstimator.java 30 Aug 2003 23:16:52 -0000 1.2
+++ FFTTimeEstimator.java 29 Oct 2003 21:53:23 -0000 1.3
@@ -16,11 +16,11 @@
public class FFTTimeEstimator extends ResponseTimeEstimator {
- BigDecimal [][]signal = new BigDecimal[RECENT_LENGTH][2];
+ BigDecimal [][]signal = new BigDecimal[RecentReports.RECENT_LENGTH][2];
BigDecimal [][]eigenValues;
//TODO: these arrays will be removed. hopefully
- double [][]signal_double = new double[RECENT_LENGTH][2];
+ double [][]signal_double = new double[RecentReports.RECENT_LENGTH][2];
double [][]eigenValues_double;
//bogus constructor
@@ -32,33 +32,28 @@
//overriden to use FFT on all points
public synchronized void report (Key k, int usec) {
BigInteger n = convert(k);
+ recent.report(n,usec);
- recentKeys[recentPtr] = n;
- recentTimes[recentPtr] = usec;
- signal[recentPtr][0]=new BigDecimal(n);
- signal[recentPtr][1]=new BigDecimal((double)usec);
+ signal[recent.recentPtr][0]=new BigDecimal(n);
+ signal[recent.recentPtr][1]=new BigDecimal((double)usec);
//pad with 0s only if total number of measurements less than history size
- for (int i = recentCount;i<RECENT_LENGTH;i++) {
+ for (int i = recent.recentCount;i<recent.RECENT_LENGTH;i++) {
signal[i][0]= new BigDecimal(BigInteger.ZERO);
signal[i][1]= new BigDecimal(BigInteger.ZERO);
}
//TODO: get rid of this
- signal_double[recentPtr][0] = signal[recentPtr][0].doubleValue();
- signal_double[recentPtr][1] = signal[recentPtr][1].doubleValue();
- for (int i = recentCount;i<RECENT_LENGTH;i++) {
+ signal_double[recent.recentPtr][0] = signal[recent.recentPtr][0].doubleValue();
+ signal_double[recent.recentPtr][1] = signal[recent.recentPtr][1].doubleValue();
+ for (int i = recent.recentCount;i<recent.RECENT_LENGTH;i++) {
signal_double[i][0]= 0;
signal_double[i][1]= 0;
}
//TODO: make this use the full accuracy
eigenValues_double = fft_1d(signal_double);
-
- recentCount++;
- recentPtr++;
- if(recentPtr >= RECENT_LENGTH) recentPtr = 0;
}
//overriden to use FFT on all points
Index: NGRoutingTable.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/node/rt/NGRoutingTable.java,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -w -r1.19 -r1.20
--- NGRoutingTable.java 26 Oct 2003 01:26:21 -0000 1.19
+++ NGRoutingTable.java 29 Oct 2003 21:53:23 -0000 1.20
@@ -336,12 +336,8 @@
props[5] = new Long(totalConnectSuccesses);
props[6] = new Float(pLegitDNF);
props[7] = new Float(pSemiLegitDNF);
- props[8] = new String(globalEstimator.
-
formatFromRaw(globalEstimator.lowestRaw(),
-
globalEstimator.TIME));
- props[9] = new String(globalEstimator.
-
formatFromRaw(globalEstimator.highestRaw(),
-
globalEstimator.TIME));
+ props[8] = new
String(globalEstimator.getHTMLReportingTool().lowestString(globalEstimator.TIME));
+ props[9] = new
String(globalEstimator.getHTMLReportingTool().highestString(globalEstimator.TIME));
props[10] = getClass().getName();
StringMap sm = new SimpleStringMap(TABLE_PROPERTIES, props);
// FIXME!
_______________________________________________
cvs mailing list
[EMAIL PROTECTED]
http://dodo.freenetproject.org/cgi-bin/mailman/listinfo/cvs