Author: toad
Date: 2006-09-09 16:03:43 +0000 (Sat, 09 Sep 2006)
New Revision: 10441

Modified:
   trunk/freenet/src/freenet/node/KeyTracker.java
   trunk/freenet/src/freenet/support/LimitedRangeIntByteArrayMap.java
   trunk/freenet/src/freenet/support/LimitedRangeIntByteArrayMapElement.java
Log:
Reinstate 10416, with a major bugfix and a sanity check.
Don't resend packets more than once every 4 RTTs.



Modified: trunk/freenet/src/freenet/node/KeyTracker.java
===================================================================
--- trunk/freenet/src/freenet/node/KeyTracker.java      2006-09-08 22:36:47 UTC 
(rev 10440)
+++ trunk/freenet/src/freenet/node/KeyTracker.java      2006-09-09 16:03:43 UTC 
(rev 10441)
@@ -309,10 +309,12 @@
     private class QueuedAckRequest extends BaseQueuedResend {

        final long createdTime;
+       long activeDelay;

        long initialActiveTime(long now) {
-            // 500ms after sending packet, send ackrequest
-            return now + 500;
+               // Request an ack after four RTTs
+               activeDelay = fourRTTs();
+               return now + activeDelay;
         }

         QueuedAckRequest(int packetNumber, boolean sendSoon) {
@@ -369,6 +371,11 @@
         queueAck(seqNumber);
     }

+    public long fourRTTs() {
+       // FIXME upper bound necessary ?
+       return (long) Math.min(Math.max(500, pn.averagePingTime()*4), 5000);
+    }
+    
     protected void receivedPacketNumber(int seqNumber) {
        if(logMINOR) Logger.minor(this, "Handling received packet number 
"+seqNumber);
         queueResendRequests(seqNumber);
@@ -899,18 +906,25 @@
      */
     public ResendPacketItem[] grabResendPackets() {
         int[] numbers;
+        long now = System.currentTimeMillis();
+        long fourRTTs = fourRTTs();
+        int count=0;
         synchronized(packetsToResend) {
             int len = packetsToResend.size();
             numbers = new int[len];
-            int i=0;
             for(Iterator it=packetsToResend.iterator();it.hasNext();) {
                 int packetNo = ((Integer)it.next()).intValue();
-                numbers[i++] = packetNo;
+                long resentTime = sentPacketsContents.getReaddedTime(packetNo);
+                if(now - resentTime > fourRTTs) {
+                       // Either never resent, or resent at least 4 RTTs ago
+                       numbers[count++] = packetNo;
+                       it.remove();
+                }
             }
             packetsToResend.clear();
         }
         ResendPacketItem[] items = new ResendPacketItem[numbers.length];
-        for(int i=0;i<numbers.length;i++) {
+        for(int i=0;i<count;i++) {
             int packetNo = numbers[i];
             byte[] buf = sentPacketsContents.get(packetNo);
             if(buf == null) {

Modified: trunk/freenet/src/freenet/support/LimitedRangeIntByteArrayMap.java
===================================================================
--- trunk/freenet/src/freenet/support/LimitedRangeIntByteArrayMap.java  
2006-09-08 22:36:47 UTC (rev 10440)
+++ trunk/freenet/src/freenet/support/LimitedRangeIntByteArrayMap.java  
2006-09-09 16:03:43 UTC (rev 10441)
@@ -67,6 +67,17 @@
     }

     /**
+     * Get the time at which an index was re-added last.
+     */
+    public synchronized long getReaddedTime(int index) {
+       Integer i = new Integer(index);
+       LimitedRangeIntByteArrayMapElement wrapper = 
(LimitedRangeIntByteArrayMapElement) contents.get(i);
+       if(wrapper != null)
+               return wrapper.reputTime;
+       else return -1;
+    }
+    
+    /**
      * Try to add an index/data mapping.
      * @return True if we succeeded, false if the index was out
      * of range.
@@ -89,7 +100,12 @@
             minValue = index;
         }
         if(data == null) throw new NullPointerException();
-        contents.put(new Integer(index), new 
LimitedRangeIntByteArrayMapElement(index, data, callbacks));
+        Integer i = new Integer(index);
+        LimitedRangeIntByteArrayMapElement le = 
(LimitedRangeIntByteArrayMapElement) contents.get(i);
+        if(le == null)
+               contents.put(new Integer(index), new 
LimitedRangeIntByteArrayMapElement(index, data, callbacks));
+        else
+               le.reput();
         notifyAll();
         return true;
     }

Modified: 
trunk/freenet/src/freenet/support/LimitedRangeIntByteArrayMapElement.java
===================================================================
--- trunk/freenet/src/freenet/support/LimitedRangeIntByteArrayMapElement.java   
2006-09-08 22:36:47 UTC (rev 10440)
+++ trunk/freenet/src/freenet/support/LimitedRangeIntByteArrayMapElement.java   
2006-09-09 16:03:43 UTC (rev 10441)
@@ -16,7 +16,7 @@
     public final byte[] data;
     public final AsyncMessageCallback[] callbacks;
     public final long createdTime;
-    long reputTime = -1; /* Do NOT get rid of the initialisation otherwise 
calling LimitedRangeIntByteArrayMap.getReaddedTime() might return bullshit */
+    long reputTime = -1; /* Should only be set to a real time when we are 
re-added the first time */

        public void reput() {
                this.reputTime = System.currentTimeMillis();


Reply via email to