Author: toad
Date: 2008-02-28 16:41:08 +0000 (Thu, 28 Feb 2008)
New Revision: 18205

Modified:
   trunk/freenet/src/freenet/io/xfer/PacketThrottle.java
Log:
Shrink the window if we don't use all of it.

Modified: trunk/freenet/src/freenet/io/xfer/PacketThrottle.java
===================================================================
--- trunk/freenet/src/freenet/io/xfer/PacketThrottle.java       2008-02-28 
16:12:52 UTC (rev 18204)
+++ trunk/freenet/src/freenet/io/xfer/PacketThrottle.java       2008-02-28 
16:41:08 UTC (rev 18205)
@@ -50,6 +50,12 @@
        private boolean slowStart = true;
        /** Total packets in flight, including waiting for bandwidth from the 
central throttle. */
        private int _packetsInFlight;
+       /** Incremented on each send */
+       private long _packetSeq;
+       /** Last time (seqno) the window was full */
+       private long _packetSeqWindowFull;
+       /** Last time (seqno) we checked whether the window was full, or 
dropped a packet. */
+       private long _packetSeqWindowFullChecked;

        /**
         * Create a PacketThrottle for a given peer.
@@ -83,10 +89,25 @@
                slowStart = false;
                if(Logger.shouldLog(Logger.MINOR, this))
                        Logger.minor(this, "notifyOfPacketLost(): "+this);
+               _packetSeqWindowFullChecked = _packetSeq;
     }

     public synchronized void notifyOfPacketAcknowledged() {
         _totalPackets++;
+               // If we didn't use the whole window, shrink the window a bit.
+               // This is similar but not identical to RFC2861
+               // See [freenet-dev] Major weakness in our current link-level 
congestion control
+        int windowSize = (int)getWindowSize();
+        if(_packetSeqWindowFullChecked + windowSize < _packetSeq) {
+               if(_packetSeqWindowFull < _packetSeqWindowFullChecked) {
+                       // We haven't used the full window once since we last 
checked.
+                       _packetSeqWindowFull *= PACKET_DROP_DECREASE_MULTIPLE;
+               _packetSeqWindowFullChecked += windowSize;
+                       return;
+               }
+               _packetSeqWindowFullChecked += windowSize;
+        }
+
        if(slowStart) {
                _simulatedWindowSize += _simulatedWindowSize / 
SLOW_START_DIVISOR;
        } else {
@@ -150,6 +171,10 @@
                                int windowSize = (int) getWindowSize();
                                if(_packetsInFlight < windowSize) {
                                        _packetsInFlight++;
+                                       _packetSeq++;
+                                       if(windowSize == _packetsInFlight) {
+                                               _packetSeqWindowFull = 
_packetSeq;
+                                       }
                                        break;
                                }
                                try {


Reply via email to