Author: nextgens
Date: 2006-07-02 12:15:13 +0000 (Sun, 02 Jul 2006)
New Revision: 9421

Added:
   trunk/freenet/src/freenet/client/async/PrioritySchedulerCallback.java
Modified:
   trunk/freenet/src/freenet/client/async/ClientRequestScheduler.java
   trunk/freenet/src/freenet/node/Version.java
Log:
849:
        * enforce the use of a tweaked "soft" priority scheduler.

Modified: trunk/freenet/src/freenet/client/async/ClientRequestScheduler.java
===================================================================
--- trunk/freenet/src/freenet/client/async/ClientRequestScheduler.java  
2006-07-02 09:11:35 UTC (rev 9420)
+++ trunk/freenet/src/freenet/client/async/ClientRequestScheduler.java  
2006-07-02 12:15:13 UTC (rev 9421)
@@ -11,7 +11,6 @@
 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;
@@ -22,7 +21,7 @@
  * thread. It is removed at that point.
  */
 public class ClientRequestScheduler implements RequestScheduler {
-
+       
        /**
         * Structure:
         * array (by priority) -> // one element per possible priority
@@ -40,8 +39,13 @@
        private final RequestStarter starter;
        private final Node node;

+       public static final String PRIORITY_NONE = "NONE";
+       public static final String PRIORITY_SOFT = "SOFT";
+       public static final String PRIORITY_HARD = "HARD";
+       private String choosen_priority_scheduler; 
+       
        // FIXME : shoudln't be hardcoded !
-       private int[] prioritySelecter = { 
+       private int[] tweakedPrioritySelector = { 
                        0, 0, 0, 0, 0, 0, 0,
                        1, 1, 1, 1, 1, 1,
                        2, 2, 2, 2, 2,
@@ -50,6 +54,7 @@
                        5, 5,
                        6 
        };
+       private int[] prioritySelector = { 0, 1, 2, 3, 4, 5, 6 };

        public ClientRequestScheduler(boolean forInserts, boolean forSSKs, 
RandomSource random, RequestStarter starter, Node node) {
                this.starter = starter;
@@ -59,8 +64,19 @@
                this.isSSKScheduler = forSSKs;
                priorities = new 
SortedVectorByNumber[RequestStarter.NUMBER_OF_PRIORITY_CLASSES];
                allRequestsByClientRequest = new HashMap();
+               
+               //FIXME implement the config. hook
+               this.choosen_priority_scheduler = PRIORITY_SOFT;
        }

+       /** Called by the  config. Callback
+        * 
+        * @param val
+        */
+       protected void setPriorityScheduler(String val){
+               choosen_priority_scheduler = val;
+       }
+       
        public void register(SendableRequest req) {
                Logger.minor(this, "Registering "+req, new Exception("debug"));
                if((!isInsertScheduler) && req instanceof ClientPutter)
@@ -100,7 +116,7 @@
                v.add(req);
                Logger.minor(this, "Registered "+req+" on 
prioclass="+req.getPriorityClass()+", retrycount="+req.getRetryCount());
        }
-
+       
        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)");
@@ -125,21 +141,50 @@
                }
                clientGrabber.add(cr, req);
        }
-
+       
+       private SortedVectorByNumber removeFirstAccordingToPriorities(){
+               SortedVectorByNumber result = null;
+               int priority;
+               
+               if(choosen_priority_scheduler.equals(PRIORITY_SOFT)){
+                       short fuzz=-1, iteration = 0;
+                       
+                       // we loop to ensure we try every possibilities
+                       while(iteration++ < priorities.length){
+                               priority = fuzz<0 ? 
tweakedPrioritySelector[random.nextInt(tweakedPrioritySelector.length)] : 
prioritySelector[Math.abs(fuzz % prioritySelector.length)];
+                               result = priorities[priority];
+                               if(result != null)      
+                                       return result;
+                               
+                               Logger.minor(this, "Priority "+priority+" is 
null (fuzz = "+fuzz+")");
+                               fuzz++;
+                       }
+                       
+                       return null;
+               }else if(choosen_priority_scheduler.equals(PRIORITY_HARD)){
+                       // FIXME: maybe use an iterator ?
+                       for(priority=0 ; priority< prioritySelector.length ; 
priority++){
+                               result = priorities[priority];
+                               if(result != null)
+                                       return result;
+                               else
+                                       Logger.minor(this, "Priority 
"+priority+" is null");
+                       }
+               }
+               //FIXME : implement "NONE"
+               
+               return result;
+       }
+       
        public SendableRequest removeFirst() {
                // Priorities start at 0
                Logger.minor(this, "removeFirst()");
-               for(int i=0;i<RequestStarter.MINIMUM_PRIORITY_CLASS;i++) {
-                       SortedVectorByNumber s = priorities[i];
-                       if(s == null) {
-                               Logger.minor(this, "Priority "+i+" is null");
-                               continue;
-                       }
+               SortedVectorByNumber s = removeFirstAccordingToPriorities();
+               if(s != null){
                        while(true) {
-                               SectoredRandomGrabArrayWithInt rga = 
(SectoredRandomGrabArrayWithInt) s.getFirst(); // will discard finished items
+                               SectoredRandomGrabArrayWithInt rga = 
(SectoredRandomGrabArrayWithInt) s.getFirst();
                                if(rga == null) {
-                                       Logger.minor(this, "No retrycount's in 
priority "+i);
-                                       priorities[i] = null;
+                                       Logger.minor(this, "No retrycount's 
left");
                                        break;
                                }
                                SendableRequest req = (SendableRequest) 
rga.removeRandom();
@@ -147,20 +192,14 @@
                                        Logger.minor(this, "Removing retrycount 
"+rga.getNumber());
                                        s.remove(rga.getNumber());
                                        if(s.isEmpty()) {
-                                               Logger.minor(this, "Removing 
priority "+i);
-                                               priorities[i] = null;
+                                               Logger.minor(this, "Should 
remove priority ");
                                        }
                                }
                                if(req == null) {
-                                       Logger.minor(this, "No requests in 
priority "+i+", retrycount "+rga.getNumber()+" ("+rga+")");
-                                       continue;
+                                       Logger.minor(this, "No requests, 
retrycount "+rga.getNumber()+" ("+rga+")");
+                                       break;
                                }
-                               if(req.getPriorityClass() > i) {
-                                       // Reinsert it
-                                       Logger.minor(this, "In wrong priority 
class: "+req);
-                                       innerRegister(req);
-                                       continue;
-                               }
+                               
                                Logger.minor(this, "removeFirst() returning 
"+req+" ("+rga.getNumber()+")");
                                ClientRequester cr = req.getClientRequest();
                                HashSet v = (HashSet) 
allRequestsByClientRequest.get(cr);
@@ -173,7 +212,7 @@
                Logger.minor(this, "No requests to run");
                return null;
        }
-
+       
        public void reregisterAll(ClientRequester request) {
                synchronized(this) {
                        HashSet h = (HashSet) 
allRequestsByClientRequest.get(request);

Added: trunk/freenet/src/freenet/client/async/PrioritySchedulerCallback.java
===================================================================
--- trunk/freenet/src/freenet/client/async/PrioritySchedulerCallback.java       
2006-07-02 09:11:35 UTC (rev 9420)
+++ trunk/freenet/src/freenet/client/async/PrioritySchedulerCallback.java       
2006-07-02 12:15:13 UTC (rev 9421)
@@ -0,0 +1,32 @@
+package freenet.client.async;
+
+import freenet.config.InvalidConfigValueException;
+import freenet.config.StringCallback;
+
+public class PrioritySchedulerCallback implements StringCallback{
+       String value;
+       ClientRequestScheduler cs;
+       
+       PrioritySchedulerCallback(ClientRequestScheduler cs){
+               this.value = new String(ClientRequestScheduler.PRIORITY_HARD);
+               this.cs = cs;
+       }
+       
+       public String get(){
+               return value;
+       }
+       
+       public void set(String val) throws InvalidConfigValueException{
+               if(val.equalsIgnoreCase(get())) return;
+               if(val.equalsIgnoreCase(ClientRequestScheduler.PRIORITY_HARD)){
+                       value = ClientRequestScheduler.PRIORITY_HARD;
+               }else 
if(val.equalsIgnoreCase(ClientRequestScheduler.PRIORITY_SOFT)){
+                       value = ClientRequestScheduler.PRIORITY_SOFT;
+               }else 
if(val.equalsIgnoreCase(ClientRequestScheduler.PRIORITY_NONE)){
+                       value = ClientRequestScheduler.PRIORITY_NONE;
+               }else{
+                       throw new InvalidConfigValueException("The value 
"+val+" isn't valid.");
+               }
+               cs.setPriorityScheduler(value);
+       }
+}
\ No newline at end of file

Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2006-07-02 09:11:35 UTC (rev 
9420)
+++ trunk/freenet/src/freenet/node/Version.java 2006-07-02 12:15:13 UTC (rev 
9421)
@@ -18,7 +18,7 @@
        public static final String protocolVersion = "1.0";

        /** The build number of the current revision */
-       private static final int buildNumber = 848;
+       private static final int buildNumber = 849;

        /** Oldest build of Fred we will talk to */
        private static final int oldLastGoodBuild = 839;


Reply via email to