Author: zothar
Date: 2006-12-19 19:39:11 +0000 (Tue, 19 Dec 2006)
New Revision: 11491
Modified:
trunk/freenet/src/freenet/clients/http/StatisticsToadlet.java
trunk/freenet/src/freenet/node/LocationManager.java
trunk/freenet/src/freenet/node/Node.java
Log:
Re-introduce offsetMe to the peer circle to make the local node stand out
better and easier to find. The distance from the edge of the peer circle is a
function of the probability that the peer will reject our request (pReject).
Add a second circle for the node location distribution of swaps we've seen.
The distance from the edge of the node location distribution circle indicates
how long ago we last saw that location, up to 24 hours. Add a "center point"
to the circle code. Re-introduce mark location precision reduction to the
circle code, now forcing the formatting to the US locale, which should fix the
broken circle issue in locales where comma is used as a decimal separator, so
it should work for Jogy now. Increase the size of the circle div slightly for
the new location of offsetMe.
Modified: trunk/freenet/src/freenet/clients/http/StatisticsToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/StatisticsToadlet.java
2006-12-19 19:18:16 UTC (rev 11490)
+++ trunk/freenet/src/freenet/clients/http/StatisticsToadlet.java
2006-12-19 19:39:11 UTC (rev 11491)
@@ -3,10 +3,13 @@
import java.io.IOException;
import java.net.URI;
import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.util.Arrays;
import java.util.Comparator;
+import java.util.HashMap;
import java.util.Iterator;
+import java.util.Locale;
import java.util.Map;
import freenet.client.HighLevelSimpleClient;
@@ -529,9 +532,16 @@
overviewTableRow = overviewTable.addChild("tr");
nextTableCell = overviewTableRow.addChild("td",
"class", "first");
HTMLNode peerCircleInfobox =
nextTableCell.addChild("div", "class", "infobox");
- peerCircleInfobox.addChild("div", "class",
"infobox-header", "Peer Location Distribution");
+ peerCircleInfobox.addChild("div", "class",
"infobox-header", "Peer\u00a0Location\u00a0Distribution (w/pReject)");
HTMLNode peerCircleInfoboxContent =
peerCircleInfobox.addChild("div", "class", "infobox-content");
addPeerCircle(peerCircleInfoboxContent);
+
+ // node distribution box
+ nextTableCell = overviewTableRow.addChild("td",
"class", "first");
+ HTMLNode nodeCircleInfobox =
nextTableCell.addChild("div", "class", "infobox");
+ nodeCircleInfobox.addChild("div", "class",
"infobox-header", "Node\u00a0Location\u00a0Distribution (w/Swap\u00a0Age)");
+ HTMLNode nodeCircleInfoboxContent =
nodeCircleInfobox.addChild("div", "class", "infobox-content");
+ addNodeCircle(nodeCircleInfoboxContent);
}
}
@@ -539,34 +549,75 @@
}
private final static int PEER_CIRCLE_RADIUS = 100;
- private final DecimalFormat fix4p2 = new DecimalFormat("###0.0#");
+ private final static int PEER_CIRCLE_INNER_RADIUS = 60;
+ private final static long MAX_CIRCLE_AGE_THRESHOLD = 24l*60*60*1000;
// 24 hours
+ private final DecimalFormat fix3p1 = new DecimalFormat("##0.0", new
DecimalFormatSymbols(Locale.US));
+ private void addNodeCircle (HTMLNode htmlNode) {
+ HTMLNode nodeCircleInfoboxContentDiv = htmlNode.addChild("div",
new String[] { "style", "class" }, new String[] {"position: relative; height: "
+ (PEER_CIRCLE_RADIUS * 2 + 15) + "px", "peercircle" });
+ nodeCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] { generatePeerCircleStyleString(0, false,
1.0), "mark" }, "|");
+ nodeCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] { generatePeerCircleStyleString(0.125, false,
1.0), "mark" }, "+");
+ nodeCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] { generatePeerCircleStyleString(0.25, false,
1.0), "mark" }, "--");
+ nodeCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] { generatePeerCircleStyleString(0.375, false,
1.0), "mark" }, "+");
+ nodeCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] { generatePeerCircleStyleString(0.5, false,
1.0), "mark" }, "|");
+ nodeCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] { generatePeerCircleStyleString(0.625, false,
1.0), "mark" }, "+");
+ nodeCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] { generatePeerCircleStyleString(0.75, false,
1.0), "mark" }, "--");
+ nodeCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] { generatePeerCircleStyleString(0.875, false,
1.0), "mark" }, "+");
+ nodeCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] { generatePeerCircleStyleString(0.875, false,
1.0), "mark" }, "+");
+ nodeCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] { "position: absolute; top: " +
PEER_CIRCLE_RADIUS + "px; left: " + PEER_CIRCLE_RADIUS + "px", "mark" }, "+");
+ HashMap knownLocsCopy = node.getKnownLocations(-1);
+ Double location = new Double(0.0);
+ Long locationTime = new Long(0);
+ double strength = 1.0;
+ long now = System.currentTimeMillis();
+ long age = 1;
+ Iterator knownLocationsIterator =
knownLocsCopy.keySet().iterator();
+ while (knownLocationsIterator.hasNext()) {
+ location = (Double) knownLocationsIterator.next();
+ locationTime = (Long) knownLocsCopy.get(location);
+ age = now - locationTime.longValue();
+ if( age > MAX_CIRCLE_AGE_THRESHOLD ) {
+ age = MAX_CIRCLE_AGE_THRESHOLD;
+ }
+ strength = 1 - ((double) age / MAX_CIRCLE_AGE_THRESHOLD
);
+ nodeCircleInfoboxContentDiv.addChild("span", new
String[] { "style", "class" }, new String[] {
generatePeerCircleStyleString(location.doubleValue(), false, strength),
"connected" }, "x");
+ }
+ nodeCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] {
generatePeerCircleStyleString(node.getLocation(), true, 1.0), "me" }, "x");
+ }
+
private void addPeerCircle (HTMLNode htmlNode) {
- HTMLNode peerCircleInfoboxContentDiv = htmlNode.addChild("div",
new String[] { "style", "class" }, new String[] {"position: relative; height: "
+ (PEER_CIRCLE_RADIUS * 2 + 10) + "px", "peercircle" });
- peerCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] { generatePeerCircleStyleString(0), "mark"
}, "|");
- peerCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] { generatePeerCircleStyleString(0.125), "mark"
}, "+");
- peerCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] { generatePeerCircleStyleString(0.25), "mark"
}, "--");
- peerCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] { generatePeerCircleStyleString(0.375), "mark"
}, "+");
- peerCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] { generatePeerCircleStyleString(0.5), "mark"
}, "|");
- peerCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] { generatePeerCircleStyleString(0.625), "mark"
}, "+");
- peerCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] { generatePeerCircleStyleString(0.75), "mark"
}, "--");
- peerCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] { generatePeerCircleStyleString(0.875), "mark"
}, "+");
+ HTMLNode peerCircleInfoboxContentDiv = htmlNode.addChild("div",
new String[] { "style", "class" }, new String[] {"position: relative; height: "
+ (PEER_CIRCLE_RADIUS * 2 + 15) + "px", "peercircle" });
+ peerCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] { generatePeerCircleStyleString(0, false,
1.0), "mark" }, "|");
+ peerCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] { generatePeerCircleStyleString(0.125, false,
1.0), "mark" }, "+");
+ peerCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] { generatePeerCircleStyleString(0.25, false,
1.0), "mark" }, "--");
+ peerCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] { generatePeerCircleStyleString(0.375, false,
1.0), "mark" }, "+");
+ peerCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] { generatePeerCircleStyleString(0.5, false,
1.0), "mark" }, "|");
+ peerCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] { generatePeerCircleStyleString(0.625, false,
1.0), "mark" }, "+");
+ peerCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] { generatePeerCircleStyleString(0.75, false,
1.0), "mark" }, "--");
+ peerCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] { "position: absolute; top: " +
PEER_CIRCLE_RADIUS + "px; left: " + PEER_CIRCLE_RADIUS + "px", "mark" }, "+");
//
PeerNodeStatus[] peerNodeStatuses = node.getPeerNodeStatuses();
for (int peerIndex = 0, peerCount = peerNodeStatuses.length;
peerIndex < peerCount; peerIndex++) {
- PeerNodeStatus peerNodeStatus =
peerNodeStatuses[peerIndex];
- peerCircleInfoboxContentDiv.addChild("span",
new String[] { "style", "class" }, new String[] {
generatePeerCircleStyleString(peerNodeStatus.getLocation()),
((peerNodeStatus.isConnected())?"connected":"disconnected") }, "x");
+ PeerNodeStatus peerNodeStatus =
peerNodeStatuses[peerIndex];
+ peerCircleInfoboxContentDiv.addChild("span", new
String[] { "style", "class" }, new String[] {
generatePeerCircleStyleString(peerNodeStatus.getLocation(), false, (1.0 -
peerNodeStatus.getPReject())),
((peerNodeStatus.isConnected())?"connected":"disconnected") }, "x");
}
//
- peerCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] {
generatePeerCircleStyleString(node.getLocation()), "me" }, "x");
+ peerCircleInfoboxContentDiv.addChild("span", new String[] {
"style", "class" }, new String[] {
generatePeerCircleStyleString(node.getLocation(), true, 1.0), "me" }, "x");
}
- private String generatePeerCircleStyleString (double peerLocation) {
+ private String generatePeerCircleStyleString (double peerLocation,
boolean offsetMe, double strength) {
peerLocation *= Math.PI * 2;
//
- int x = (int)(PEER_CIRCLE_RADIUS + Math.sin(peerLocation) *
PEER_CIRCLE_RADIUS);
- int y = (int)(PEER_CIRCLE_RADIUS - Math.cos(peerLocation) *
PEER_CIRCLE_RADIUS);
+ int offset = 0;
+ if( offsetMe ) {
+ // Make our own peer stand out from the crowd better so we
can see it easier
+ offset = -10;
+ } else {
+ offset = (int) (((double) PEER_CIRCLE_INNER_RADIUS) *
(1.0 - strength));
+ }
+ double x = PEER_CIRCLE_RADIUS + Math.sin(peerLocation) *
(PEER_CIRCLE_RADIUS - offset);
+ double y = PEER_CIRCLE_RADIUS - Math.cos(peerLocation) *
(PEER_CIRCLE_RADIUS - offset);
//
- return "position: absolute; top: " + y + "px; left: " + x +
"px";
+ return "position: absolute; top: " + fix3p1.format(y) + "px;
left: " + fix3p1.format(x) + "px";
}
}
Modified: trunk/freenet/src/freenet/node/LocationManager.java
===================================================================
--- trunk/freenet/src/freenet/node/LocationManager.java 2006-12-19 19:18:16 UTC
(rev 11490)
+++ trunk/freenet/src/freenet/node/LocationManager.java 2006-12-19 19:39:11 UTC
(rev 11491)
@@ -1062,4 +1062,28 @@
}
return size;
}
+
+ // Return a copy of the known locations HashMap for a given timestamp
+ public HashMap getKnownLocations(long timestamp) {
+ if (timestamp > -1) {
+ HashMap knownLocsCopy = new HashMap();
+ //TODO optimize some more if it is to be called a lot.
+ Double location = new Double(0.0);
+ Long locationTime = new Long(0);
+ Iterator knownLocationsIterator =
knownLocs.keySet().iterator();
+ while (knownLocationsIterator.hasNext()) {
+ location = (Double)
knownLocationsIterator.next();
+ locationTime = (Long)
knownLocs.get(location);
+ if (locationTime.longValue() >
timestamp) {
+ //If the location is already
recorded, remove it from the hashmap
+ if
(knownLocsCopy.containsKey(location)) {
+
knownLocsCopy.remove(location);
+ }
+ knownLocsCopy.put(location,
locationTime);
+ }
+ }
+ return knownLocsCopy;
+ }
+ return new HashMap( knownLocs );
+ }
}
Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java 2006-12-19 19:18:16 UTC (rev
11490)
+++ trunk/freenet/src/freenet/node/Node.java 2006-12-19 19:39:11 UTC (rev
11491)
@@ -2943,6 +2943,10 @@
public int getNetworkSizeEstimate(long timestamp) {
return lm.getNetworkSizeEstimate( timestamp );
}
+
+ public HashMap getKnownLocations(long timestamp) {
+ return lm.getKnownLocations( timestamp );
+ }
public int getSwaps() {
return LocationManager.swaps;