This should be a config option, obviously. I do think the priority
scheduling policy should be a separate option; we may have other tweaks
we can do to scheduling, so just having a choice of scheduler isn't
good.
BTW why did you not remove the priority? Locking? Hmmm, are we seriously
short of locks here?
On Sun, Jul 02, 2006 at 12:15:22PM +0000, nextgens at freenetproject.org wrote:
> 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;
>
> _______________________________________________
> cvs mailing list
> cvs at freenetproject.org
> http://emu.freenetproject.org/cgi-bin/mailman/listinfo/cvs
>
--
Matthew J Toseland - toad at amphibian.dyndns.org
Freenet Project Official Codemonkey - http://freenetproject.org/
ICTHUS - Nothing is impossible. Our Boss says so.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL:
<https://emu.freenetproject.org/pipermail/cvs/attachments/20060703/9a4eb417/attachment.pgp>