Fixed. Attached patch includes my previous work on a histogram of keys in the datastore by size, I can separate this if people object. The easiest way to deal with this is to give me CVS write access. Next stop, P(success).
? src/freenet/support/KeySizeHistogram.java
Index: src/freenet/Core.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/Core.java,v
retrieving revision 1.10
diff -u -r1.10 Core.java
--- src/freenet/Core.java 25 Apr 2002 05:02:37 -0000 1.10
+++ src/freenet/Core.java 22 Jun 2002 22:38:07 -0000
@@ -211,6 +211,9 @@
/** Distribution of inbound requests over the keyspace. **/
public static KeyHistogram requestDistribution = null;
+ /** Distribution of successful inbound requests over the keyspace **/
+ public static KeyHistogram successDistribution = null;
+
/**
* Sets the logging object to be used for logging messages
* @param log a Logger object that will log messages to an output stream.
Index: src/freenet/client/http/NodeStatusServlet.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/client/http/NodeStatusServlet.java,v
retrieving revision 1.26
diff -u -r1.26 NodeStatusServlet.java
--- src/freenet/client/http/NodeStatusServlet.java 30 May 2002 23:56:51 -0000
1.26
+++ src/freenet/client/http/NodeStatusServlet.java 22 Jun 2002 22:38:11 -0000
@@ -41,6 +41,7 @@
import freenet.support.StringMap;
import freenet.support.SimpleStringMap;
import freenet.support.KeyHistogram;
+import freenet.support.KeySizeHistogram;
import freenet.support.graph.BitmapEncoder;
/*
@@ -141,6 +142,11 @@
return;
}
+ if (uri.endsWith("ds_size_histogram.txt")) {
+ sendDSSizeHistogram(resp, false);
+ return;
+ };
+
if (uri.endsWith("inbound_request_histogram.txt")) {
int[] bins = null;
if (node.requestDistribution != null) {
@@ -149,10 +155,21 @@
sendKeyHistogram(resp, false, bins,
"Histogram of requested keys.",
"This count has nothing to do with keys in your
datastore",
- MSG_NO_REQUEST_DIST);
+ MSG_NO_REQUEST_DIST, "keys", false);
return;
}
+ if(uri.endsWith("inbound_success_histogram.txt")) {
+ int [] bins = null;
+ if (node.successDistribution != null) {
+ bins = node.successDistribution.getBins();
+ }
+ sendKeyHistogram(resp, false, bins,
+ "Histogram of successfully requested keys.",
+ "This count has nothing to do with keys in your
+datastore",
+ MSG_NO_REQUEST_DIST, "keys", false);
+ return;
+ }
if (uri.endsWith("key_histogram_data.txt")) {
sendRTHistogram(resp, true);
@@ -164,6 +181,11 @@
return;
}
+ if (uri.endsWith("ds_size_histogram_data.txt")) {
+ sendDSSizeHistogram(resp, true);
+ return;
+ }
+
if (uri.endsWith("inbound_request_histogram_data.txt")) {
int[] bins = null;
if (node.requestDistribution != null) {
@@ -173,11 +195,24 @@
sendKeyHistogram(resp, true, bins,
"Histogram of requested keys.",
"This count has nothing to do with keys in your
datastore",
- MSG_NO_REQUEST_DIST);
+ MSG_NO_REQUEST_DIST, "keys", false);
return;
}
+ if (uri.endsWith("inbound_success_histogram_data.txt")) {
+ int[] bins = null;
+ if (node.successDistribution != null) {
+ bins = node.successDistribution.getBins();
+ }
+
+ sendKeyHistogram(resp, true, bins,
+ "Histogram of successfully requested keys.",
+ "This count has nothing to do with keys in your
+datastore",
+ MSG_NO_REQUEST_DIST, "keys", false);
+ return;
+ }
+
if (uri.endsWith("noderefs.txt")) {
sendRefList(req, resp);
}
@@ -338,13 +373,20 @@
pw.println(" <li> <a href=\"" + baseURL + "ds_histogram.txt\"> " +
" Histogram of keys in the local DataStore. </a>" +
"     <em>Note: Slow. Be patient. </em> ");
- pw.println(" <a href= \"" + baseURL +
- "ds_histogram_data.txt\">" +
+ pw.println(" <li> <a href= \"" + baseURL +
+ "ds_histogram_data.txt\"> " +
"<br>(flat ascii)</a><br>");
-
- pw.println(" <li> <em> TODO: We need distribution data for
succcessful requests. </em>");
- pw.println(" <br>I'm really busy these days. It would be
cool if someone could code");
- pw.println(" this up. --gj");
+ pw.println(" <li> <a href=\"" + baseURL + "ds_size_histogram.txt\">
+" +
+ " Histogram of sizes of keys in local DataStore. </a>");
+ pw.println(" <li> <a href= \"" + baseURL +
+ "ds_size_histogram_data.txt\">" +
+ "<br>(flat ascii)</a><br>");
+
+ pw.println(" <li> <a href=\"" + baseURL +
+"inbound_success_histogram.txt\"> " +
+ " Histogram of successful inbound request search keys </a>");
+ pw.println(" <li> <a href=\"" + baseURL +
+ "inbound_success_histogram_data.txt\">" +
+ "<br>(flat ascii)</a><br>");
pw.println(" </ul> <p>");
pw.println(" <li> <a href=\"" + baseURL +"diagnostics/index.html\">
Diagnostics Values </a> <p>");
pw.println(" <li> <a href=\"" + baseURL +"inboundContacts.txt\"> Inbound
Contact Attempts </a> <br>");
@@ -392,7 +434,7 @@
}
private final static String drawLine(int binNum, int freq) {
- String ret = Integer.toString(binNum, 16) + " |";
+ String ret = "";
for (int i = 0; i < freq; i++) {
ret += "=";
}
@@ -486,7 +528,8 @@
"Histogram of keys in in fred's Routing table",
"This count has nothing to do with keys in your datastore, "
+
"these keys are used for routing",
- MSG_OOPS /* bins should always be non-null */);
+ MSG_OOPS /* bins should always be non-null */,
+ "keys", false);
}
@@ -499,13 +542,28 @@
"Histogram of keys in in fred's data store",
"These are the keys to the data in your node's " +
"local cache (DataStore)",
- MSG_OOPS /* bins should always be non-null */);
+ MSG_OOPS /* bins should always be non-null */,
+ "keys", false);
}
+ private void sendDSSizeHistogram(HttpServletResponse resp, boolean justData)
+throws IOException {
+
+ FSDataStore ds = (FSDataStore) node.ds;
+ KeySizeHistogram histogram = ds.getSizeHistogram();
+
+ sendKeyHistogram(resp, justData, histogram.getBins(),
+ "Histogram of sizes of keys in fred's data store",
+ "These are the numbers of keys in your DataStore" +
+ " of (roughly) each size",
+ MSG_OOPS /* bins should always be non-null */, "keys",
+ true);
+ }
+
private void sendKeyHistogram(HttpServletResponse resp, boolean justData, int[]
bins,
String title, String comment,
- String complaint) throws IOException {
+ String complaint, String commodity,
+ boolean exponential) throws IOException {
if (bins == null) {
resp.setStatus(HttpServletResponse.SC_OK);
@@ -526,7 +584,7 @@
}
}
- float scale = 1.0f;
+ double scale = 1.0f;
if (maximum > 64) {
// REDFLAG: test
// Scale factor for ASCII limits line lengths to 64
@@ -543,24 +601,40 @@
if (justData) {
pw.println("# " + title);
pw.println("# " + date);
- pw.println("# keys: " + count);
+ pw.println("# " + commodity + ": " + count);
}
else {
pw.println(title);
pw.println(comment);
pw.println(date);
- pw.println("keys: " + count);
+ pw.println(commodity + ": " + count);
pw.println("scale factor: " + scale + " (This is used to keep lines < 64
characters)");
pw.println("");
}
for (i = 0; i < bins.length; i++) {
+ String line;
+ if(exponential)
+ {
+ line = shortPowerString(10+i);
+ if(i == (bins.length-1))
+ {
+ line += "+";
+ };
+ }
+ else
+ {
+ line = Integer.toString(i, 16);
+ };
if (justData) {
- pw.println(i + "\t" + bins[i] );
+ line += "\t" + bins[i];
}
else {
- pw.println(drawLine(i, ((int)(bins[i] * scale))));
+ if(!exponential || (i != (bins.length-1))) line += " ";
+ while(line.length()<5) { line = " " + line; };
+ line += "|" + drawLine(i, ((int)(bins[i] * scale)));
}
+ pw.println(line);
}
pw.println("");
@@ -572,6 +646,19 @@
resp.flushBuffer();
}
+ private String shortPowerString(int power)
+ {
+ int x = power % 10;
+ if(x==10) x = 0;
+ String ret = Integer.toString(1 << x);
+ char SI[] = {'k','M','G','T','P','E'};
+ if(power >= 10)
+ {
+ ret += SI[(power/10)-1];
+ };
+ return ret;
+ };
+
private void sendStatusPage(HttpServletResponse resp) throws IOException {
long now = System.currentTimeMillis();
DateFormat df = DateFormat.getDateTimeInstance();
Index: src/freenet/node/Main.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/node/Main.java,v
retrieving revision 1.44
diff -u -r1.44 Main.java
--- src/freenet/node/Main.java 1 Jun 2002 22:01:03 -0000 1.44
+++ src/freenet/node/Main.java 22 Jun 2002 22:38:16 -0000
@@ -635,6 +635,10 @@
Core.requestDistribution = new KeyHistogram();
}
+ // Non-optional because we want to use it for request
+ // triage in overload
+ Core.successDistribution = new KeyHistogram();
+
// the FCP interface
SessionHandler clientSh = new SessionHandler();
clientSh.register(new FnpLinkManager(), 10);
Index: src/freenet/node/ds/FSDataStore.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/node/ds/FSDataStore.java,v
retrieving revision 1.6
diff -u -r1.6 FSDataStore.java
--- src/freenet/node/ds/FSDataStore.java 25 Apr 2002 05:02:37 -0000 1.6
+++ src/freenet/node/ds/FSDataStore.java 22 Jun 2002 22:38:16 -0000
@@ -261,6 +261,27 @@
return histogram;
}
+ public KeySizeHistogram getSizeHistogram() {
+ KeySizeHistogram histogram = new KeySizeHistogram();
+
+ synchronized (dir.semaphore()) {
+ Enumeration keys = dir.keys(true);
+ while (keys.hasMoreElements()) {
+ FileNumber fn = (FileNumber) keys.nextElement();
+ Buffer buffer = dir.fetch(fn);
+ try {
+ histogram.add( new Key(fn.getByteArray()), buffer.length() );
+ }
+ finally
+ {
+ buffer.release();
+ }
+ }
+ }
+
+ return histogram;
+ }
+
private static final class KeyWalk implements Walk {
private final Walk fnw;
KeyWalk(Walk fnw) {
Index: src/freenet/node/states/request/AwaitingStoreData.java
===================================================================
RCS file:
/cvsroot/freenet/freenet/src/freenet/node/states/request/AwaitingStoreData.java,v
retrieving revision 1.5
diff -u -r1.5 AwaitingStoreData.java
--- src/freenet/node/states/request/AwaitingStoreData.java 25 Mar 2002 22:18:44
-0000 1.5
+++ src/freenet/node/states/request/AwaitingStoreData.java 22 Jun 2002 22:38:17
+-0000
@@ -76,7 +76,17 @@
}
// yay!
routes.routeSucceeded();
- // Update global network load estimate stats.
+
+ // Update successful request distribution
+ if (n.successDistribution != null)
+ {
+ if(origPeer != null)
+ {
+ n.successDistribution.add(searchKey);
+ };
+ };
+
+ // Update global network load estimate stats.
n.loadStats.storeRequestRateForNode(sd.dataSource(), sd.requestsPerHour());
relayStoreData(n, sd);
package freenet.support;
import freenet.Key;
public class KeySizeHistogram {
public synchronized void add(Key key, long len) {
int binNumber = 0;
int i = 2048;
for(binNumber=0; i<len;)
{
i <<= 1;
binNumber++;
};
if(binNumber < 0) binNumber = 0;
if(binNumber > 15) binNumber = 15;
bins[binNumber]++;
}
// Distribution of keys with most significant nibbles 0-f.
public synchronized int[] getBins() {
int[] ret = new int[bins.length];
System.arraycopy(bins, 0, ret, 0, bins.length);
return ret;
}
private int bins[] = new int[21];
}
msg03319/pgp00000.pgp
Description: PGP signature
