Author: nextgens
Date: 2008-08-08 11:02:09 +0000 (Fri, 08 Aug 2008)
New Revision: 21662
Modified:
trunk/freenet/src/freenet/clients/http/ConnectionsToadlet.java
trunk/freenet/src/freenet/clients/http/staticfiles/themes/clean/theme.css
trunk/freenet/src/freenet/node/PeerManager.java
trunk/freenet/src/freenet/node/PeerNode.java
trunk/freenet/src/freenet/node/PeerNodeStatus.java
Log:
FOAF: make the peer selection stats time decaying
maybe we should implement it using a bit field... and maybe 30% is too much
Modified: trunk/freenet/src/freenet/clients/http/ConnectionsToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/ConnectionsToadlet.java
2008-08-08 10:29:07 UTC (rev 21661)
+++ trunk/freenet/src/freenet/clients/http/ConnectionsToadlet.java
2008-08-08 11:02:09 UTC (rev 21662)
@@ -120,7 +120,8 @@
long total2 =
secondNode.getTotalInputBytes()+secondNode.getTotalOutputBytes();
return compareLongs(total1, total2);
}else if(sortBy.equals("selection_percentage")){
- return
compareLongs(firstNode.getNumberOfSelections(),
secondNode.getNumberOfSelections());
+ long sinceWhen = System.currentTimeMillis() -
PeerNode.SELECTION_SAMPLING_PERIOD;
+ return
compareInts(firstNode.getNumberOfSelections().headSet(sinceWhen).size(),
secondNode.getNumberOfSelections().headSet(sinceWhen).size());
}else if(sortBy.equals("time_delta")){
return compareLongs(firstNode.getClockDelta(),
secondNode.getClockDelta());
}else if(sortBy.equals(("uptime"))){
@@ -418,9 +419,8 @@
}
}
- long numberOfSelectionSamples =
peers.getNumberOfSelectionSamples();
- for (int peerIndex = 0, peerCount =
peerNodeStatuses.length; peerIndex < peerCount; peerIndex++) {
-
+ int numberOfSelectionSamples =
peers.getNumberOfSelectionSamples().tailSet(now -
PeerNode.SELECTION_SAMPLING_PERIOD).size();
+ for (int peerIndex = 0, peerCount =
peerNodeStatuses.length; peerIndex < peerCount; peerIndex++) {
PeerNodeStatus peerNodeStatus =
peerNodeStatuses[peerIndex];
drawRow(peerTable, peerNodeStatus, mode
>= PageMaker.MODE_ADVANCED, fProxyJavascriptEnabled, now, path,
enablePeerActions, endCols, drawMessageTypes, numberOfSelectionSamples);
@@ -693,9 +693,11 @@
abstract protected SimpleFieldSet getNoderef();
- private void drawRow(HTMLNode peerTable, PeerNodeStatus peerNodeStatus,
boolean advancedModeEnabled, boolean fProxyJavascriptEnabled, long now, String
path, boolean enablePeerActions, SimpleColumn[] endCols, boolean
drawMessageTypes, long numberOfSelectionSamples) {
- HTMLNode peerRow = peerTable.addChild("tr");
-
+ private void drawRow(HTMLNode peerTable, PeerNodeStatus peerNodeStatus,
boolean advancedModeEnabled, boolean fProxyJavascriptEnabled, long now, String
path, boolean enablePeerActions, SimpleColumn[] endCols, boolean
drawMessageTypes, int numberOfSelectionSamples) {
+ int peerSelectionCount =
peerNodeStatus.getNumberOfSelections().tailSet(now -
PeerNode.SELECTION_SAMPLING_PERIOD).size();
+ int peerSelectionPercentage = (numberOfSelectionSamples > 0 ?
(peerSelectionCount*100/numberOfSelectionSamples) : 0);
+ HTMLNode peerRow = peerTable.addChild("tr", "class",
"darknet_connections_"+(peerSelectionPercentage >
PeerNode.SELECTION_PERCENTAGE_WARNING ? "warning" : "normal"));
+
if(enablePeerActions) {
// check box column
peerRow.addChild("td", "class",
"peer-marker").addChild("input", new String[] { "type", "name" }, new String[]
{ "checkbox", "node_" + peerNodeStatus.hashCode() });
@@ -775,7 +777,7 @@
// percent of time connected column
peerRow.addChild("td", "class", "peer-idle" /* FIXME
*/).addChild("#",
fix1.format(peerNodeStatus.getPercentTimeRoutableConnection()));
// selection stats
- peerRow.addChild("td", "class", "peer-idle" /* FIXME
*/).addChild("#", (numberOfSelectionSamples > 0 ?
((peerNodeStatus.getNumberOfSelections()*100/numberOfSelectionSamples)+"%") :
"N/A"));
+ peerRow.addChild("td", "class", "peer-idle" /* FIXME
*/).addChild("#", (numberOfSelectionSamples > 0 ? (peerSelectionPercentage+"%")
: "N/A"));
// total traffic column
peerRow.addChild("td", "class", "peer-idle" /* FIXME
*/).addChild("#", SizeUtil.formatSize(peerNodeStatus.getTotalInputBytes())+" /
"+SizeUtil.formatSize(peerNodeStatus.getTotalOutputBytes())+"/"+SizeUtil.formatSize(peerNodeStatus.getResendBytesSent()));
// congestion control
Modified:
trunk/freenet/src/freenet/clients/http/staticfiles/themes/clean/theme.css
===================================================================
--- trunk/freenet/src/freenet/clients/http/staticfiles/themes/clean/theme.css
2008-08-08 10:29:07 UTC (rev 21661)
+++ trunk/freenet/src/freenet/clients/http/staticfiles/themes/clean/theme.css
2008-08-08 11:02:09 UTC (rev 21662)
@@ -378,6 +378,10 @@
text-align: center;
}
+tr.darknet_connections_warning {
+ background-color: #ffff00;
+}
+
table.sentmessagetypes {
display: inline;
}
Modified: trunk/freenet/src/freenet/node/PeerManager.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerManager.java 2008-08-08 10:29:07 UTC
(rev 21661)
+++ trunk/freenet/src/freenet/node/PeerManager.java 2008-08-08 11:02:09 UTC
(rev 21662)
@@ -38,6 +38,8 @@
import freenet.support.SimpleFieldSet;
import freenet.support.io.FileUtil;
import freenet.support.io.Closer;
+import java.util.SortedSet;
+import java.util.TreeSet;
/**
* @author amphibian
@@ -79,9 +81,14 @@
private long nextRoutableConnectionStatsUpdateTime = -1;
/** routableConnectionStats update interval (milliseconds) */
private static final long routableConnectionStatsUpdateInterval = 7 *
1000; // 7 seconds
- /** number of samples we have to do stats on peer-selection */
- private long numberOfSelectionSamples = 0;
+ /**
+ * Track the number of times a PeerNode has been selected by the
routing algorithm
+ * @see PeerNode.numberOfSelections
+ */
+ private SortedSet<Long> numberOfSelectionSamples = new TreeSet<Long>();
+ private final Object numberOfSelectionSamplesSync = new Object();
+
public static final int PEER_NODE_STATUS_CONNECTED = 1;
public static final int PEER_NODE_STATUS_ROUTING_BACKED_OFF = 2;
public static final int PEER_NODE_STATUS_TOO_NEW = 3;
@@ -991,10 +998,8 @@
//Add the location which we did not pick, if it
exists.
if(closestNotBackedOff != null &&
closestBackedOff != null)
addUnpickedLocsTo.add(new
Double(closestBackedOff.getLocation()));
-
- //TODO: synchronize! ; store the stats here instead of
into PeerNode?
- best.incrementNumberOfSelections();
- numberOfSelectionSamples++;
+
+ incrementSelectionSamples(now, best);
}
return best;
@@ -1824,7 +1829,19 @@
return null;
}
- public long getNumberOfSelectionSamples() {
- return numberOfSelectionSamples;
+ public SortedSet<Long> getNumberOfSelectionSamples() {
+ synchronized (numberOfSelectionSamplesSync) {
+ return new TreeSet<Long>(numberOfSelectionSamples);
+ }
}
+
+ private void incrementSelectionSamples(long now, PeerNode pn) {
+ // TODO: reimplement with a bit field to spare memory
+ synchronized (numberOfSelectionSamplesSync) {
+ if(numberOfSelectionSamples.size() >
PeerNode.SELECTION_MAX_SAMPLES * OpennetManager.MAX_PEERS_FOR_SCALING)
+ numberOfSelectionSamples =
numberOfSelectionSamples.tailSet(now - PeerNode.SELECTION_SAMPLING_PERIOD);
+ numberOfSelectionSamples.add(now);
+ pn.incrementNumberOfSelections(now);
+ }
+ }
}
Modified: trunk/freenet/src/freenet/node/PeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNode.java 2008-08-08 10:29:07 UTC
(rev 21661)
+++ trunk/freenet/src/freenet/node/PeerNode.java 2008-08-08 11:02:09 UTC
(rev 21662)
@@ -74,7 +74,8 @@
import freenet.support.math.TimeDecayingRunningAverage;
import freenet.support.transport.ip.HostnameSyntaxException;
import freenet.support.transport.ip.IPUtil;
-import java.util.Collection;
+import java.util.SortedSet;
+import java.util.TreeSet;
/**
* @author amphibian
@@ -151,9 +152,21 @@
private long timeLastRoutable;
/** Time added or restarted (reset on startup unlike peerAddedTime) */
private long timeAddedOrRestarted;
- /** Number of time that peer has been selected by the routing algorithm
*/
- private long numberOfSelections = 0;
+ /**
+ * Track the number of times this PeerNode has been selected by
+ * the routing algorithm over a given period of time
+ */
+ private SortedSet<Long> numberOfSelections = new TreeSet<Long>();
+ private final Object numberOfSelectionsSync = new Object();
+ // 5mins; yes it's alchemy!
+ public static final int SELECTION_SAMPLING_PERIOD = 5 * 60 * 1000;
+ // 30%; yes it's alchemy too! and probably *way* too high to serve any
purpose
+ public static final int SELECTION_PERCENTAGE_WARNING = 30;
+ // Should be good enough provided we don't get selected more than 10
times per/sec
+ // Lower the following value if you want to spare memory... or better
switch from a TreeSet to a bit field.
+ public static final int SELECTION_MAX_SAMPLES = 10 *
SELECTION_SAMPLING_PERIOD / 1000;
+
/** Are we connected? If not, we need to start trying to
* handshake.
*/
@@ -3990,12 +4003,19 @@
return (short)(((int)uptime) & 0xFF);
}
- public long getNumberOfSelections() {
- return numberOfSelections;
+ public SortedSet<Long> getNumberOfSelections() {
+ synchronized(numberOfSelectionsSync) {
+ return new TreeSet<Long>(numberOfSelections);
+ }
}
- public void incrementNumberOfSelections() {
- numberOfSelections++;
+ public void incrementNumberOfSelections(long time) {
+ // TODO: reimplement with a bit field to spare memory
+ synchronized(numberOfSelectionsSync) {
+ if(numberOfSelections.size() > SELECTION_MAX_SAMPLES)
+ numberOfSelections =
numberOfSelections.tailSet(time - SELECTION_SAMPLING_PERIOD);
+ numberOfSelections.add(time);
+ }
}
private long offeredMainJarVersion;
Modified: trunk/freenet/src/freenet/node/PeerNodeStatus.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNodeStatus.java 2008-08-08 10:29:07 UTC
(rev 21661)
+++ trunk/freenet/src/freenet/node/PeerNodeStatus.java 2008-08-08 11:02:09 UTC
(rev 21662)
@@ -8,6 +8,7 @@
import freenet.io.comm.Peer;
import freenet.io.xfer.PacketThrottle;
import freenet.support.Logger;
+import java.util.SortedSet;
/**
* Contains various status information for a {@link PeerNode}. Used e.g. in
@@ -94,7 +95,7 @@
private final int reportedUptimePercentage;
- private final long numberOfSelections;
+ private final SortedSet<Long> numberOfSelections;
PeerNodeStatus(PeerNode peerNode, boolean noHeavy) {
if(Logger.shouldLog(Logger.MINOR, this)) {
@@ -397,7 +398,7 @@
return reportedUptimePercentage;
}
- public long getNumberOfSelections() {
+ public SortedSet<Long> getNumberOfSelections() {
return numberOfSelections;
}
}