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();