Author: toad
Date: 2006-06-22 02:07:01 +0000 (Thu, 22 Jun 2006)
New Revision: 9349
Added:
trunk/freenet/src/freenet/support/RemoveRandom.java
trunk/freenet/src/freenet/support/RemoveRandomWithClient.java
trunk/freenet/src/freenet/support/SectoredRandomGrabArrayWithClient.java
Modified:
trunk/freenet/src/freenet/client/async/ClientRequestScheduler.java
trunk/freenet/src/freenet/node/Version.java
trunk/freenet/src/freenet/support/RandomGrabArrayWithClient.java
trunk/freenet/src/freenet/support/SectoredRandomGrabArray.java
trunk/freenet/src/freenet/support/SortedVectorByNumber.java
Log:
836: Make scheduler allocate equal time to all ClientRequest's within a client.
Not fully tested - third party testing very welcome: queue two files at the
same priority, one big and one small; the small one should finish first.
Modified: trunk/freenet/src/freenet/client/async/ClientRequestScheduler.java
===================================================================
--- trunk/freenet/src/freenet/client/async/ClientRequestScheduler.java
2006-06-22 01:59:51 UTC (rev 9348)
+++ trunk/freenet/src/freenet/client/async/ClientRequestScheduler.java
2006-06-22 02:07:01 UTC (rev 9349)
@@ -11,6 +11,8 @@
import freenet.node.Node;
import freenet.node.RequestStarter;
import freenet.support.Logger;
+import freenet.support.SectoredRandomGrabArray;
+import freenet.support.SectoredRandomGrabArrayWithClient;
import freenet.support.SectoredRandomGrabArrayWithInt;
import freenet.support.SortedVectorByNumber;
@@ -89,9 +91,7 @@
}
private synchronized void innerRegister(SendableRequest req) {
- SectoredRandomGrabArrayWithInt grabber =
- makeGrabArray(req.getPriorityClass(),
req.getRetryCount());
- grabber.add(req.getClient(), req);
+ addToGrabArray(req.getPriorityClass(), req.getRetryCount(),
req.getClient(), req.getClientRequest(), req);
HashSet v = (HashSet)
allRequestsByClientRequest.get(req.getClientRequest());
if(v == null) {
v = new HashSet();
@@ -101,21 +101,29 @@
Logger.minor(this, "Registered "+req+" on
prioclass="+req.getPriorityClass()+", retrycount="+req.getRetryCount());
}
- private synchronized SectoredRandomGrabArrayWithInt makeGrabArray(short
priorityClass, int retryCount) {
+ private synchronized void addToGrabArray(short priorityClass, int
retryCount, Object client, ClientRequester cr, SendableRequest req) {
if(priorityClass > RequestStarter.MINIMUM_PRIORITY_CLASS ||
priorityClass < RequestStarter.MAXIMUM_PRIORITY_CLASS)
throw new IllegalStateException("Invalid priority:
"+priorityClass+" - range is "+RequestStarter.MAXIMUM_PRIORITY_CLASS+" (most
important) to "+RequestStarter.MINIMUM_PRIORITY_CLASS+" (least important)");
+ // Priority
SortedVectorByNumber prio = priorities[priorityClass];
if(prio == null) {
prio = new SortedVectorByNumber();
priorities[priorityClass] = prio;
}
- SectoredRandomGrabArrayWithInt grabber =
(SectoredRandomGrabArrayWithInt) prio.get(retryCount);
- if(grabber == null) {
- grabber = new SectoredRandomGrabArrayWithInt(random,
retryCount);
- prio.add(grabber);
+ // Client
+ SectoredRandomGrabArrayWithInt clientGrabber =
(SectoredRandomGrabArrayWithInt) prio.get(retryCount);
+ if(clientGrabber == null) {
+ clientGrabber = new
SectoredRandomGrabArrayWithInt(random, retryCount);
+ prio.add(clientGrabber);
Logger.minor(this, "Registering retry count
"+retryCount+" with prioclass "+priorityClass);
}
- return grabber;
+ // Request
+ SectoredRandomGrabArrayWithClient requestGrabber =
(SectoredRandomGrabArrayWithClient) clientGrabber.getGrabber(cr);
+ if(requestGrabber == null) {
+ requestGrabber = new
SectoredRandomGrabArrayWithClient(cr, random);
+ clientGrabber.addGrabber(cr, requestGrabber);
+ }
+ clientGrabber.add(client, req);
}
public synchronized SendableRequest removeFirst() {
Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2006-06-22 01:59:51 UTC (rev
9348)
+++ trunk/freenet/src/freenet/node/Version.java 2006-06-22 02:07:01 UTC (rev
9349)
@@ -18,7 +18,7 @@
public static final String protocolVersion = "1.0";
/** The build number of the current revision */
- private static final int buildNumber = 835;
+ private static final int buildNumber = 836;
/** Oldest build of Fred we will talk to */
private static final int lastGoodBuild = 765;
Modified: trunk/freenet/src/freenet/support/RandomGrabArrayWithClient.java
===================================================================
--- trunk/freenet/src/freenet/support/RandomGrabArrayWithClient.java
2006-06-22 01:59:51 UTC (rev 9348)
+++ trunk/freenet/src/freenet/support/RandomGrabArrayWithClient.java
2006-06-22 02:07:01 UTC (rev 9349)
@@ -2,7 +2,7 @@
import freenet.crypt.RandomSource;
-public class RandomGrabArrayWithClient extends RandomGrabArray {
+public class RandomGrabArrayWithClient extends RandomGrabArray implements
RemoveRandomWithClient {
final Object client;
@@ -11,4 +11,7 @@
this.client = client;
}
+ public final Object getClient() {
+ return client;
+ }
}
Added: trunk/freenet/src/freenet/support/RemoveRandom.java
===================================================================
--- trunk/freenet/src/freenet/support/RemoveRandom.java 2006-06-22 01:59:51 UTC
(rev 9348)
+++ trunk/freenet/src/freenet/support/RemoveRandom.java 2006-06-22 02:07:01 UTC
(rev 9349)
@@ -0,0 +1,8 @@
+package freenet.support;
+
+public interface RemoveRandom {
+
+ /** Remove and return a random RandomGrabArrayItem. Should be fast. */
+ public RandomGrabArrayItem removeRandom();
+
+}
Added: trunk/freenet/src/freenet/support/RemoveRandomWithClient.java
===================================================================
--- trunk/freenet/src/freenet/support/RemoveRandomWithClient.java
2006-06-22 01:59:51 UTC (rev 9348)
+++ trunk/freenet/src/freenet/support/RemoveRandomWithClient.java
2006-06-22 02:07:01 UTC (rev 9349)
@@ -0,0 +1,9 @@
+package freenet.support;
+
+public interface RemoveRandomWithClient extends RemoveRandom {
+
+ public Object getClient();
+
+ public boolean isEmpty();
+
+}
Modified: trunk/freenet/src/freenet/support/SectoredRandomGrabArray.java
===================================================================
--- trunk/freenet/src/freenet/support/SectoredRandomGrabArray.java
2006-06-22 01:59:51 UTC (rev 9348)
+++ trunk/freenet/src/freenet/support/SectoredRandomGrabArray.java
2006-06-22 02:07:01 UTC (rev 9349)
@@ -8,10 +8,10 @@
* Like RandomGrabArray, but there is an equal chance of any given client's
requests being
* returned.
*/
-public class SectoredRandomGrabArray {
+public class SectoredRandomGrabArray implements RemoveRandom {
private final HashMap grabArraysByClient;
- private RandomGrabArrayWithClient[] grabArrays;
+ private RemoveRandomWithClient[] grabArrays;
private final RandomSource rand;
public SectoredRandomGrabArray(RandomSource rand) {
@@ -19,7 +19,9 @@
this.grabArraysByClient = new HashMap();
grabArrays = new RandomGrabArrayWithClient[0];
}
-
+
+ /**
+ * Add directly to a RandomGrabArrayWithClient under us. */
public synchronized void add(Object client, RandomGrabArrayItem item) {
RandomGrabArrayWithClient rga;
if(!grabArraysByClient.containsKey(client)) {
@@ -34,15 +36,31 @@
}
rga.add(item);
}
-
+
+ /**
+ * Get a grabber. This lets us use things other than
RandomGrabArrayWithClient's, so don't mix calls
+ * to add() with calls to getGrabber/addGrabber!
+ */
+ public synchronized RemoveRandomWithClient getGrabber(Object client) {
+ return (RemoveRandomWithClient) grabArraysByClient.get(client);
+ }
+
+ /**
+ * Put a grabber. This lets us use things other than
RandomGrabArrayWithClient's, so don't mix calls
+ * to add() with calls to getGrabber/addGrabber!
+ */
+ public synchronized void addGrabber(Object client,
RemoveRandomWithClient requestGrabber) {
+ grabArraysByClient.put(client, requestGrabber);
+ }
+
public synchronized RandomGrabArrayItem removeRandom() {
while(true) {
if(grabArrays.length == 0) return null;
int x = rand.nextInt(grabArrays.length);
- RandomGrabArrayWithClient rga = grabArrays[x];
+ RemoveRandomWithClient rga = grabArrays[x];
RandomGrabArrayItem item = rga.removeRandom();
if(rga.isEmpty() || item == null) {
- Object client = rga.client;
+ Object client = rga.getClient();
grabArraysByClient.remove(client);
RandomGrabArrayWithClient[] newArray = new
RandomGrabArrayWithClient[grabArrays.length-1];
if(x > 0)
Added: trunk/freenet/src/freenet/support/SectoredRandomGrabArrayWithClient.java
===================================================================
--- trunk/freenet/src/freenet/support/SectoredRandomGrabArrayWithClient.java
2006-06-22 01:59:51 UTC (rev 9348)
+++ trunk/freenet/src/freenet/support/SectoredRandomGrabArrayWithClient.java
2006-06-22 02:07:01 UTC (rev 9349)
@@ -0,0 +1,18 @@
+package freenet.support;
+
+import freenet.crypt.RandomSource;
+
+public class SectoredRandomGrabArrayWithClient extends SectoredRandomGrabArray
implements RemoveRandomWithClient {
+
+ private final Object client;
+
+ public SectoredRandomGrabArrayWithClient(Object client, RandomSource
rand) {
+ super(rand);
+ this.client = client;
+ }
+
+ public Object getClient() {
+ return client;
+ }
+
+}
Modified: trunk/freenet/src/freenet/support/SortedVectorByNumber.java
===================================================================
--- trunk/freenet/src/freenet/support/SortedVectorByNumber.java 2006-06-22
01:59:51 UTC (rev 9348)
+++ trunk/freenet/src/freenet/support/SortedVectorByNumber.java 2006-06-22
02:07:01 UTC (rev 9349)
@@ -3,6 +3,8 @@
import java.util.Arrays;
import java.util.Comparator;
+import freenet.client.async.ClientRequester;
+
/**
* Map of an integer to an element, based on a sorted Vector.
* Note that we have to shuffle data around, so this is slowish if it gets big.