Author: toad
Date: 2008-03-11 17:19:36 +0000 (Tue, 11 Mar 2008)
New Revision: 18465

Modified:
   trunk/freenet/src/freenet/node/NodeStats.java
Log:
Assume 70% overhead for the first 5 minutes after initial connection. Then 
calculate it from the known byte overheads.

Modified: trunk/freenet/src/freenet/node/NodeStats.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeStats.java       2008-03-11 17:18:52 UTC 
(rev 18464)
+++ trunk/freenet/src/freenet/node/NodeStats.java       2008-03-11 17:19:36 UTC 
(rev 18465)
@@ -55,9 +55,6 @@
         */
        public static final int MAX_INTERREQUEST_TIME = 10*1000;

-       /** Fudge factor for high level bandwidth limiting. FIXME should be a 
long term running average */
-       public static final double FRACTION_OF_BANDWIDTH_USED_BY_REQUESTS = 0.8;
-
        private final Node node;
        private MemoryChecker myMemoryChecker;
        public final PeerManager peers;
@@ -302,9 +299,9 @@
                remoteFetchPSuccess = new TrivialRunningAverage();

                requestOutputThrottle = 
-                       new TokenBucket(Math.max(obwLimit*60, 32768*20), 
(int)((1000L*1000L*1000L) / (obwLimit * 
FRACTION_OF_BANDWIDTH_USED_BY_REQUESTS)), 0);
+                       new TokenBucket(Math.max(obwLimit*60, 32768*20), 
(int)((1000L*1000L*1000L) / (obwLimit)), 0);
                requestInputThrottle = 
-                       new TokenBucket(Math.max(ibwLimit*60, 32768*20), 
(int)((1000L*1000L*1000L) / (ibwLimit * 
FRACTION_OF_BANDWIDTH_USED_BY_REQUESTS)), 0);
+                       new TokenBucket(Math.max(ibwLimit*60, 32768*20), 
(int)((1000L*1000L*1000L) / (ibwLimit)), 0);

                estimatedSizeOfOneThrottledPacket = 1024 + 
DMT.packetTransmitSize(1024, 32) + 
                        node.estimateFullHeadersLengthOneMessage();
@@ -390,8 +387,25 @@

                double bwlimitDelayTime = 
throttledPacketSendAverage.currentValue();

+               long[] total = IOStatisticCollector.getTotalIO();
+               long totalSent = total[0];
+               long totalOverhead = getSentOverhead();
+               long uptime = node.getUptime();
+               double sentOverheadPerSecond = ((double)totalOverhead*1000.0) / 
((double)uptime);
+               /** The fraction of output bytes which are used for requests */
+               double overheadFraction = ((double)(totalSent - totalOverhead)) 
/ totalSent;
+               long timeFirstAnyConnections = peers.timeFirstAnyConnections;
+               long now = System.currentTimeMillis();
+               if(logMINOR) Logger.minor(this, "Output rate: 
"+((double)totalSent*1000.0)/uptime+" overhead rate "+sentOverheadPerSecond+" 
non-overhead fraction "+overheadFraction);
+               if(overheadFraction == 0.0 || (timeFirstAnyConnections == 0 || 
now - timeFirstAnyConnections < 5*60*1000)) {
+                       overheadFraction = 0.7;
+                       if(logMINOR) Logger.minor(this, "Adjusted overhead 
fraction: "+overheadFraction);
+                       if(overheadFraction == 0.0) {
+                               Logger.error(this, "Overhead fraction is still 
100% after 5 minutes uptime??!?");
+                       }
+               }
+               
                // If no recent reports, no packets have been sent; correct the 
average downwards.
-               long now = System.currentTimeMillis();
                double pingTime;
                pingTime = nodePinger.averagePingTime();
                synchronized(this) {
@@ -460,8 +474,7 @@
                        successfulChkOfferReplyBytesSentAverage.currentValue() 
* numCHKOfferReplies +
                        successfulSskOfferReplyBytesSentAverage.currentValue() 
* numSSKOfferReplies;
                double bandwidthAvailableOutput =
-                       node.getOutputBandwidthLimit() * 90; // 90 seconds at 
full power; we have to leave some time for the search as well
-               bandwidthAvailableOutput *= 
NodeStats.FRACTION_OF_BANDWIDTH_USED_BY_REQUESTS;
+                       (node.getOutputBandwidthLimit() - 
sentOverheadPerSecond) * 90; // 90 seconds at full power; we have to leave some 
time for the search as well
                if(bandwidthLiabilityOutput > bandwidthAvailableOutput) {
                        pInstantRejectIncoming.report(1.0);
                        rejected("Output bandwidth liability", isLocal);
@@ -477,7 +490,6 @@
                        
successfulSskOfferReplyBytesReceivedAverage.currentValue() * numSSKOfferReplies;
                double bandwidthAvailableInput =
                        node.getInputBandwidthLimit() * 90; // 90 seconds at 
full power
-               bandwidthAvailableInput *= 
NodeStats.FRACTION_OF_BANDWIDTH_USED_BY_REQUESTS;
                if(bandwidthLiabilityInput > bandwidthAvailableInput) {
                        pInstantRejectIncoming.report(1.0);
                        rejected("Input bandwidth liability", isLocal);
@@ -487,7 +499,7 @@

                // Do we have the bandwidth?
                double expected = this.getThrottle(isLocal, isInsert, isSSK, 
true).currentValue();
-               int expectedSent = (int)Math.max(expected, 0);
+               int expectedSent = (int)Math.max(expected / overheadFraction, 
0);
                if(logMINOR)
                        Logger.minor(this, "Expected sent bytes: 
"+expectedSent);
                if(!requestOutputThrottle.instantGrab(expectedSent)) {
@@ -961,14 +973,14 @@
        }

        public void setOutputLimit(int obwLimit) {
-               
requestOutputThrottle.changeNanosAndBucketSize((int)((1000L*1000L*1000L) / 
(obwLimit * FRACTION_OF_BANDWIDTH_USED_BY_REQUESTS)), Math.max(obwLimit*60, 
32768*20));
+               
requestOutputThrottle.changeNanosAndBucketSize((int)((1000L*1000L*1000L) / 
(obwLimit)), Math.max(obwLimit*60, 32768*20));
                if(node.inputLimitDefault) {
                        setInputLimit(obwLimit * 4);
                }
        }

        public void setInputLimit(int ibwLimit) {
-               
requestInputThrottle.changeNanosAndBucketSize((int)((1000L*1000L*1000L) / 
(ibwLimit * FRACTION_OF_BANDWIDTH_USED_BY_REQUESTS)), Math.max(ibwLimit*60, 
32768*20));
+               
requestInputThrottle.changeNanosAndBucketSize((int)((1000L*1000L*1000L) / 
(ibwLimit)), Math.max(ibwLimit*60, 32768*20));
        }

        public boolean isTestnetEnabled() {
@@ -1096,6 +1108,9 @@
                offeredKeysSenderRcvdBytes += x;
        }

+       /**
+        * @return The number of bytes sent in replying to FNPGetOfferedKey's.
+        */
        public synchronized void offeredKeysSenderSentBytes(int x) {
                offeredKeysSenderSentBytes += x;
        }
@@ -1546,5 +1561,33 @@
        public long getNotificationOnlyPacketsSentBytes() {
                return notificationOnlySentBytes;
        }
+
+       public long getSentOverhead() {
+               return offerKeysSentBytes // offers we have sent
+               + swappingSentBytes // swapping
+               + totalAuthBytesSent // connection setup
+               + resendBytesSent // resends - FIXME might be dependant on 
requests?
+               + uomBytesSent // update over mandatory
+               + announceBytesSent // announcements
+               + routingStatusBytesSent // routing status
+               + networkColoringSentBytesCounter // network coloring
+               + pingBytesSent // ping bytes
+               + probeRequestSentBytes // probe requests
+               + routedMessageBytesSent // routed test messages
+               + disconnBytesSent // disconnection related bytes
+               + initialMessagesBytesSent // initial messages
+               + changedIPBytesSent // changed IP
+               + nodeToNodeSentBytes // n2n messages
+               + notificationOnlySentBytes; // ack-only packets
+       }

+       /**
+        * The average number of bytes sent per second for things other than 
requests, inserts,
+        * and offer replies.
+        */
+       public double getSentOverheadPerSecond() {
+               long uptime = node.getUptime();
+               return ((double)getSentOverhead() * 1000.0) / ((double) uptime);
+       }
+       
 }


Reply via email to