Author: toad
Date: 2006-01-31 22:51:28 +0000 (Tue, 31 Jan 2006)
New Revision: 7977

Added:
   trunk/freenet/src/freenet/support/RandomGrabArrayWithClient.java
   trunk/freenet/src/freenet/support/SectoredRandomGrabArray.java
   trunk/freenet/src/freenet/support/SectoredRandomGrabArrayWithInt.java
Modified:
   trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
   trunk/freenet/src/freenet/client/async/BaseClientPutter.java
   trunk/freenet/src/freenet/client/async/ClientGetter.java
   trunk/freenet/src/freenet/client/async/ClientPutter.java
   trunk/freenet/src/freenet/client/async/ClientRequest.java
   trunk/freenet/src/freenet/client/async/ClientRequestScheduler.java
   trunk/freenet/src/freenet/client/async/SendableRequest.java
   trunk/freenet/src/freenet/client/async/SimpleManifestPutter.java
   trunk/freenet/src/freenet/client/async/SingleBlockInserter.java
   trunk/freenet/src/freenet/client/async/SingleFileFetcher.java
   trunk/freenet/src/freenet/node/PeerNode.java
   trunk/freenet/src/freenet/node/Version.java
   trunk/freenet/src/freenet/node/fcp/ClientGet.java
   trunk/freenet/src/freenet/node/fcp/ClientPut.java
   trunk/freenet/src/freenet/support/SimpleFieldSet.java
Log:
421:
All clients at a given retry count and priority class are now equally likely to 
have their requests scheduled.
Include lastGoodVersion on references (not yet mandatory, treated as a simple 
string)

Modified: trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
===================================================================
--- trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java     
2006-01-31 22:01:57 UTC (rev 7976)
+++ trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java     
2006-01-31 22:51:28 UTC (rev 7977)
@@ -94,7 +94,7 @@
                if(uri == null) throw new NullPointerException();
                FetcherContext context = getFetcherContext();
                FetchWaiter fw = new FetchWaiter();
-               ClientGetter get = new ClientGetter(fw, node.fetchScheduler, 
uri, context, priorityClass);
+               ClientGetter get = new ClientGetter(fw, node.fetchScheduler, 
uri, context, priorityClass, this);
                get.start();
                return fw.waitForCompletion();
        }
@@ -107,7 +107,7 @@
                InserterContext context = getInserterContext();
                PutWaiter pw = new PutWaiter();
                ClientPutter put = new ClientPutter(pw, insert.data, 
insert.desiredURI, insert.clientMetadata, 
-                               context, node.putScheduler, priorityClass, 
getCHKOnly, isMetadata);
+                               context, node.putScheduler, priorityClass, 
getCHKOnly, isMetadata, this);
                put.start();
                return pw.waitForCompletion();
        }
@@ -129,7 +129,7 @@
        public FreenetURI insertManifest(FreenetURI insertURI, HashMap 
bucketsByName, String defaultName) throws InserterException {
                PutWaiter pw = new PutWaiter();
                SimpleManifestPutter putter =
-                       new SimpleManifestPutter(pw, node.putScheduler, 
bucketsByName, priorityClass, insertURI, defaultName, getInserterContext(), 
false);
+                       new SimpleManifestPutter(pw, node.putScheduler, 
bucketsByName, priorityClass, insertURI, defaultName, getInserterContext(), 
false, this);
                return pw.waitForCompletion();
        }


Modified: trunk/freenet/src/freenet/client/async/BaseClientPutter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/BaseClientPutter.java        
2006-01-31 22:01:57 UTC (rev 7976)
+++ trunk/freenet/src/freenet/client/async/BaseClientPutter.java        
2006-01-31 22:51:28 UTC (rev 7977)
@@ -2,8 +2,8 @@

 public abstract class BaseClientPutter extends ClientRequest {

-       protected BaseClientPutter(short priorityClass, ClientRequestScheduler 
scheduler) {
-               super(priorityClass, scheduler);
+       protected BaseClientPutter(short priorityClass, ClientRequestScheduler 
scheduler, Object context) {
+               super(priorityClass, scheduler, context);
        }

 }

Modified: trunk/freenet/src/freenet/client/async/ClientGetter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/ClientGetter.java    2006-01-31 
22:01:57 UTC (rev 7976)
+++ trunk/freenet/src/freenet/client/async/ClientGetter.java    2006-01-31 
22:51:28 UTC (rev 7977)
@@ -24,8 +24,8 @@
        private boolean finished;
        private int archiveRestarts;

-       public ClientGetter(ClientCallback client, ClientRequestScheduler 
sched, FreenetURI uri, FetcherContext ctx, short priorityClass) {
-               super(priorityClass, sched);
+       public ClientGetter(ClientCallback client, ClientRequestScheduler 
sched, FreenetURI uri, FetcherContext ctx, short priorityClass, Object 
clientContext) {
+               super(priorityClass, sched, clientContext);
                this.client = client;
                this.uri = uri;
                this.ctx = ctx;

Modified: trunk/freenet/src/freenet/client/async/ClientPutter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/ClientPutter.java    2006-01-31 
22:01:57 UTC (rev 7976)
+++ trunk/freenet/src/freenet/client/async/ClientPutter.java    2006-01-31 
22:51:28 UTC (rev 7977)
@@ -25,8 +25,8 @@
        private FreenetURI uri;

        public ClientPutter(ClientCallback client, Bucket data, FreenetURI 
targetURI, ClientMetadata cm, InserterContext ctx,
-                       ClientRequestScheduler scheduler, short priorityClass, 
boolean getCHKOnly, boolean isMetadata) {
-               super(priorityClass, scheduler);
+                       ClientRequestScheduler scheduler, short priorityClass, 
boolean getCHKOnly, boolean isMetadata, Object clientContext) {
+               super(priorityClass, scheduler, clientContext);
                this.cm = cm;
                this.isMetadata = isMetadata;
                this.getCHKOnly = getCHKOnly;

Modified: trunk/freenet/src/freenet/client/async/ClientRequest.java
===================================================================
--- trunk/freenet/src/freenet/client/async/ClientRequest.java   2006-01-31 
22:01:57 UTC (rev 7976)
+++ trunk/freenet/src/freenet/client/async/ClientRequest.java   2006-01-31 
22:51:28 UTC (rev 7977)
@@ -14,14 +14,16 @@
        protected short priorityClass;
        protected boolean cancelled;
        final ClientRequestScheduler scheduler;
+       protected final Object client;

        public short getPriorityClass() {
                return priorityClass;
        }

-       protected ClientRequest(short priorityClass, ClientRequestScheduler 
scheduler) {
+       protected ClientRequest(short priorityClass, ClientRequestScheduler 
scheduler, Object client) {
                this.priorityClass = priorityClass;
                this.scheduler = scheduler;
+               this.client = client;
        }

        public void cancel() {
@@ -97,4 +99,10 @@
        }

        public abstract void notifyClients();
+
+       /** Get client context object */
+       public Object getClient() {
+               return client;
+       }
+
 }

Modified: trunk/freenet/src/freenet/client/async/ClientRequestScheduler.java
===================================================================
--- trunk/freenet/src/freenet/client/async/ClientRequestScheduler.java  
2006-01-31 22:01:57 UTC (rev 7976)
+++ trunk/freenet/src/freenet/client/async/ClientRequestScheduler.java  
2006-01-31 22:51:28 UTC (rev 7977)
@@ -8,6 +8,7 @@
 import freenet.node.RequestStarter;
 import freenet.support.Logger;
 import freenet.support.RandomGrabArrayWithInt;
+import freenet.support.SectoredRandomGrabArrayWithInt;
 import freenet.support.SortedVectorByNumber;

 /**
@@ -62,9 +63,9 @@
                        }
                }
                synchronized(this) {
-                       RandomGrabArrayWithInt grabber = 
+                       SectoredRandomGrabArrayWithInt grabber = 
                                makeGrabArray(req.getPriorityClass(), 
req.getRetryCount());
-                       grabber.add(req);
+                       grabber.add(req.getClient(), req);
                        Logger.minor(this, "Registered "+req+" on 
prioclass="+req.getPriorityClass()+", retrycount="+req.getRetryCount());
                }
                synchronized(starter) {
@@ -72,45 +73,21 @@
                }
        }

-       private synchronized RandomGrabArrayWithInt makeGrabArray(short 
priorityClass, int retryCount) {
+       private synchronized SectoredRandomGrabArrayWithInt makeGrabArray(short 
priorityClass, int retryCount) {
                SortedVectorByNumber prio = priorities[priorityClass];
                if(prio == null) {
                        prio = new SortedVectorByNumber();
                        priorities[priorityClass] = prio;
                }
-               RandomGrabArrayWithInt grabber = (RandomGrabArrayWithInt) 
prio.get(retryCount);
+               SectoredRandomGrabArrayWithInt grabber = 
(SectoredRandomGrabArrayWithInt) prio.get(retryCount);
                if(grabber == null) {
-                       grabber = new RandomGrabArrayWithInt(random, 
retryCount);
+                       grabber = new SectoredRandomGrabArrayWithInt(random, 
retryCount);
                        prio.add(grabber);
                        Logger.minor(this, "Registering retry count 
"+retryCount+" with prioclass "+priorityClass);
                }
                return grabber;
        }

-       /**
-        * Should not be called often as can be slow if there are many requests 
of the same
-        * priority and retry count. Priority and retry count must be the same 
as they were
-        * when it was added.
-        */
-       public synchronized void remove(SendableRequest req) {
-               Logger.minor(this, "Removing "+req);
-               // Should not be called often.
-               int prio = req.getPriorityClass();
-               int retryCount = req.getRetryCount();
-               SortedVectorByNumber s = priorities[prio];
-               if(s == null) return;
-               if(s.isEmpty()) return;
-               RandomGrabArrayWithInt grabber = 
-                       (RandomGrabArrayWithInt) s.get(retryCount);
-               if(grabber == null) return;
-               grabber.remove(req);
-               if(grabber.isEmpty()) {
-                       s.remove(retryCount);
-                       if(s.isEmpty())
-                               priorities[prio] = null;
-               }
-       }
-       
        public synchronized SendableRequest removeFirst() {
                // Priorities start at 0
                Logger.minor(this, "removeFirst()");
@@ -121,7 +98,7 @@
                                continue;
                        }
                        while(true) {
-                               RandomGrabArrayWithInt rga = 
(RandomGrabArrayWithInt) s.getFirst(); // will discard finished items
+                               SectoredRandomGrabArrayWithInt rga = 
(SectoredRandomGrabArrayWithInt) s.getFirst(); // will discard finished items
                                if(rga == null) {
                                        Logger.minor(this, "No retrycount's in 
priority "+i);
                                        priorities[i] = null;

Modified: trunk/freenet/src/freenet/client/async/SendableRequest.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SendableRequest.java 2006-01-31 
22:01:57 UTC (rev 7976)
+++ trunk/freenet/src/freenet/client/async/SendableRequest.java 2006-01-31 
22:51:28 UTC (rev 7977)
@@ -16,4 +16,7 @@
        /** ONLY called by RequestStarter */
        public void send(Node node);

+       /** Get client context object */
+       public Object getClient();
+       
 }

Modified: trunk/freenet/src/freenet/client/async/SimpleManifestPutter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SimpleManifestPutter.java    
2006-01-31 22:01:57 UTC (rev 7976)
+++ trunk/freenet/src/freenet/client/async/SimpleManifestPutter.java    
2006-01-31 22:51:28 UTC (rev 7977)
@@ -24,7 +24,7 @@
        private class PutHandler extends BaseClientPutter implements 
PutCompletionCallback {

                protected PutHandler(String name, Bucket data, ClientMetadata 
cm, boolean getCHKOnly) throws InserterException {
-                       super(SimpleManifestPutter.this.getPriorityClass(), 
SimpleManifestPutter.this.scheduler);
+                       super(SimpleManifestPutter.this.getPriorityClass(), 
SimpleManifestPutter.this.scheduler, SimpleManifestPutter.this.client);
                        this.name = name;
                        this.cm = cm;
                        InsertBlock block = 
@@ -159,8 +159,8 @@

        public SimpleManifestPutter(ClientCallback cb, ClientRequestScheduler 
sched, 
                        HashMap bucketsByName, short prioClass, FreenetURI 
target, 
-                       String defaultName, InserterContext ctx, boolean 
getCHKOnly) throws InserterException {
-               super(prioClass, sched);
+                       String defaultName, InserterContext ctx, boolean 
getCHKOnly, Object clientContext) throws InserterException {
+               super(prioClass, sched, clientContext);
                this.defaultName = defaultName;
                this.targetURI = target;
                this.cb = cb;

Modified: trunk/freenet/src/freenet/client/async/SingleBlockInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SingleBlockInserter.java     
2006-01-31 22:01:57 UTC (rev 7976)
+++ trunk/freenet/src/freenet/client/async/SingleBlockInserter.java     
2006-01-31 22:51:28 UTC (rev 7977)
@@ -244,4 +244,8 @@
                onSuccess();
        }

+       public Object getClient() {
+               return parent.getClient();
+       }
+
 }

Modified: trunk/freenet/src/freenet/client/async/SingleFileFetcher.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SingleFileFetcher.java       
2006-01-31 22:01:57 UTC (rev 7976)
+++ trunk/freenet/src/freenet/client/async/SingleFileFetcher.java       
2006-01-31 22:51:28 UTC (rev 7977)
@@ -535,4 +535,8 @@
                onSuccess(block, false);
        }

+       public Object getClient() {
+               return parent.getClient();
+       }
+
 }

Modified: trunk/freenet/src/freenet/node/PeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNode.java        2006-01-31 22:01:57 UTC 
(rev 7976)
+++ trunk/freenet/src/freenet/node/PeerNode.java        2006-01-31 22:51:28 UTC 
(rev 7977)
@@ -47,6 +47,8 @@
  */
 public class PeerNode implements PeerContext {

+       private String lastGoodVersion; 
+       
     /** For debugging/testing, set this to true to stop the
      * probabilistic decrement at the edges of the HTLs.
      */
@@ -195,9 +197,11 @@
         String locationString = fs.get("location");
         if(locationString == null) throw new FSParseException("No location");
         currentLocation = new Location(locationString);
+
+        // FIXME make mandatory once everyone has upgraded
+        lastGoodVersion = fs.get("lastGoodVersion");

-        if(nominalPeer==null)
-               nominalPeer=new Vector();
+               nominalPeer=new Vector();
         nominalPeer.removeAllElements();
         try{
                String physical[]=fs.getAll("physical.udp");
@@ -838,10 +842,15 @@
         Location loc = new Location(locationString);
         if(!loc.equals(currentLocation)) changedAnything = true;
         currentLocation = loc;
-        
+
         if(nominalPeer==null)
                nominalPeer=new Vector();
         nominalPeer.removeAllElements();
+        
+        lastGoodVersion = fs.get("lastGoodVersion");
+        
+        Peer[] oldPeers = (Peer[]) nominalPeer.toArray(new 
Peer[nominalPeer.size()]);
+        
         try{
                String physical[]=fs.getAll("physical.udp");
                if(physical==null){
@@ -857,6 +866,10 @@
         } catch (Exception e1) {
                 throw new FSParseException(e1);
         }
+        
+        if(!Arrays.equals(oldPeers, nominalPeer.toArray(new 
Peer[nominalPeer.size()])))
+               changedAnything = true;
+        
         if(nominalPeer.isEmpty()) throw new FSParseException("No 
physical.udp");
         /* yes, we pick up a random one : it will be updated on handshake */
         detectedPeer=(Peer) nominalPeer.firstElement();
@@ -940,6 +953,8 @@
      */
     private SimpleFieldSet exportFieldSet() {
         SimpleFieldSet fs = new SimpleFieldSet();
+        if(lastGoodVersion != null)
+               fs.put("lastGoodVersion", lastGoodVersion);
         for(int i=0;i<nominalPeer.size();i++)
                fs.put("physical.udp", nominalPeer.get(i).toString());
         fs.put("identity", HexUtil.bytesToHex(identity));

Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2006-01-31 22:01:57 UTC (rev 
7976)
+++ trunk/freenet/src/freenet/node/Version.java 2006-01-31 22:51:28 UTC (rev 
7977)
@@ -20,7 +20,7 @@
        public static final String protocolVersion = "1.0";

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

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

Modified: trunk/freenet/src/freenet/node/fcp/ClientGet.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ClientGet.java   2006-01-31 22:01:57 UTC 
(rev 7976)
+++ trunk/freenet/src/freenet/node/fcp/ClientGet.java   2006-01-31 22:51:28 UTC 
(rev 7977)
@@ -54,7 +54,7 @@
                        throw new IllegalStateException("Unknown return type: 
"+message.returnType);
                fctx.maxOutputLength = message.maxSize;
                fctx.maxTempLength = message.maxTempSize;
-               getter = new ClientGetter(this, handler.node.fetchScheduler, 
uri, fctx, priorityClass);
+               getter = new ClientGetter(this, handler.node.fetchScheduler, 
uri, fctx, priorityClass, handler.defaultFetchContext);
                try {
                        getter.start();
                } catch (FetchException e) {

Modified: trunk/freenet/src/freenet/node/fcp/ClientPut.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ClientPut.java   2006-01-31 22:01:57 UTC 
(rev 7976)
+++ trunk/freenet/src/freenet/node/fcp/ClientPut.java   2006-01-31 22:51:28 UTC 
(rev 7977)
@@ -45,7 +45,7 @@
                uri = message.uri;
                String mimeType = message.contentType;
                block = new InsertBlock(message.bucket, new 
ClientMetadata(mimeType), uri);
-               inserter = new ClientPutter(this, message.bucket, uri, new 
ClientMetadata(mimeType), ctx, handler.node.putScheduler, priorityClass, 
getCHKOnly, false);
+               inserter = new ClientPutter(this, message.bucket, uri, new 
ClientMetadata(mimeType), ctx, handler.node.putScheduler, priorityClass, 
getCHKOnly, false, handler.defaultInsertContext);
                try {
                        inserter.start();
                } catch (InserterException e) {

Added: trunk/freenet/src/freenet/support/RandomGrabArrayWithClient.java
===================================================================
--- trunk/freenet/src/freenet/support/RandomGrabArrayWithClient.java    
2006-01-31 22:01:57 UTC (rev 7976)
+++ trunk/freenet/src/freenet/support/RandomGrabArrayWithClient.java    
2006-01-31 22:51:28 UTC (rev 7977)
@@ -0,0 +1,14 @@
+package freenet.support;
+
+import freenet.crypt.RandomSource;
+
+public class RandomGrabArrayWithClient extends RandomGrabArray {
+
+       final Object client;
+       
+       public RandomGrabArrayWithClient(Object client, RandomSource rand) {
+               super(rand);
+               this.client = client;
+       }
+
+}

Added: trunk/freenet/src/freenet/support/SectoredRandomGrabArray.java
===================================================================
--- trunk/freenet/src/freenet/support/SectoredRandomGrabArray.java      
2006-01-31 22:01:57 UTC (rev 7976)
+++ trunk/freenet/src/freenet/support/SectoredRandomGrabArray.java      
2006-01-31 22:51:28 UTC (rev 7977)
@@ -0,0 +1,61 @@
+package freenet.support;
+
+import java.util.HashMap;
+
+import freenet.crypt.RandomSource;
+
+/**
+ * Like RandomGrabArray, but there is an equal chance of any given client's 
requests being
+ * returned.
+ */
+public class SectoredRandomGrabArray {
+
+       private final HashMap grabArraysByClient;
+       private RandomGrabArrayWithClient[] grabArrays;
+       private final RandomSource rand;
+       
+       public SectoredRandomGrabArray(RandomSource rand) {
+               this.rand = rand;
+               this.grabArraysByClient = new HashMap();
+               grabArrays = new RandomGrabArrayWithClient[0];
+       }
+       
+       public synchronized void add(Object client, RandomGrabArrayItem item) {
+               RandomGrabArrayWithClient rga;
+               if(!grabArraysByClient.containsKey(client)) {
+                       rga = new RandomGrabArrayWithClient(client, rand);
+                       RandomGrabArrayWithClient[] newArrays = new 
RandomGrabArrayWithClient[grabArrays.length+1];
+                       System.arraycopy(grabArrays, 0, newArrays, 0, 
grabArrays.length);
+                       newArrays[grabArrays.length] = rga;
+                       grabArrays = newArrays;
+                       grabArraysByClient.put(client, rga);
+               } else {
+                       rga = (RandomGrabArrayWithClient) 
grabArraysByClient.get(client);
+               }
+               rga.add(item);
+       }
+       
+       public synchronized RandomGrabArrayItem removeRandom() {
+               while(true) {
+                       if(grabArrays.length == 0) return null;
+                       int x = rand.nextInt(grabArrays.length);
+                       RandomGrabArrayWithClient rga = grabArrays[x];
+                       RandomGrabArrayItem item = rga.removeRandom();
+                       if(rga.isEmpty() || item == null) {
+                               Object client = rga.client;
+                               grabArraysByClient.remove(client);
+                               RandomGrabArrayWithClient[] newArray = new 
RandomGrabArrayWithClient[grabArrays.length-1];
+                               if(x > 0)
+                                       System.arraycopy(grabArrays, 0, 
newArray, 0, x);
+                               if(x < grabArrays.length-1)
+                                       System.arraycopy(grabArrays, x+1, 
newArray, x, grabArrays.length - (x+1));
+                               grabArrays = newArray;
+                       }
+                       if(item != null) return item;
+               }
+       }
+
+       public synchronized boolean isEmpty() {
+               return grabArrays.length == 0;
+       }
+}

Added: trunk/freenet/src/freenet/support/SectoredRandomGrabArrayWithInt.java
===================================================================
--- trunk/freenet/src/freenet/support/SectoredRandomGrabArrayWithInt.java       
2006-01-31 22:01:57 UTC (rev 7976)
+++ trunk/freenet/src/freenet/support/SectoredRandomGrabArrayWithInt.java       
2006-01-31 22:51:28 UTC (rev 7977)
@@ -0,0 +1,18 @@
+package freenet.support;
+
+import freenet.crypt.RandomSource;
+
+public class SectoredRandomGrabArrayWithInt extends SectoredRandomGrabArray 
implements IntNumberedItem {
+
+       private final int number;
+
+       public SectoredRandomGrabArrayWithInt(RandomSource rand, int number) {
+               super(rand);
+               this.number = number;
+       }
+
+       public int getNumber() {
+               return number;
+       }
+       
+}

Modified: trunk/freenet/src/freenet/support/SimpleFieldSet.java
===================================================================
--- trunk/freenet/src/freenet/support/SimpleFieldSet.java       2006-01-31 
22:01:57 UTC (rev 7976)
+++ trunk/freenet/src/freenet/support/SimpleFieldSet.java       2006-01-31 
22:51:28 UTC (rev 7977)
@@ -151,17 +151,13 @@
     }

     public void put(String key, String value) {
-       String test=null;
-       try{
-               if(map.get(key) != null)
-                       test=new String((String) map.get(key));
-       }catch (Exception e){
+       String x = (String) map.get(key);
+       
+       if(x == null) {
+               map.put(key, value);
+       } else {
+               map.put(key, ((String)map.get(key))+";"+value);
        }
-       if(test != null && test.equalsIgnoreCase(value)){
-               map.put(key, test+";"+value);
-       }else{
-            map.put(key, value);               
-       }
     }

     /**


Reply via email to