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;