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.


Reply via email to