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;
        }
 }


Reply via email to