Author: toad
Date: 2008-08-28 23:04:34 +0000 (Thu, 28 Aug 2008)
New Revision: 22205

Added:
   
branches/db4o/freenet/src/freenet/client/async/PersistentSendableRequestSet.java
   branches/db4o/freenet/src/freenet/client/async/SendableRequestSet.java
   
branches/db4o/freenet/src/freenet/client/async/TransientSendableRequestSet.java
Modified:
   
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerBase.java
   
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerCore.java
   
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerNonPersistent.java
   branches/db4o/freenet/src/freenet/client/async/ClientRequester.java
   branches/db4o/freenet/src/freenet/support/SectoredRandomGrabArray.java
Log:
Store the list of SendableRequests on the ClientRequestor, using the new 
SendableRequestSet class.
For a transient request this is based on a hashmap, for a persistent one it is 
based on a vector.


Modified: 
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerBase.java
===================================================================
--- 
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerBase.java  
    2008-08-28 21:41:39 UTC (rev 22204)
+++ 
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerBase.java  
    2008-08-28 23:04:34 UTC (rev 22205)
@@ -57,7 +57,6 @@
         * To speed up fetching, a RGA or SVBN must only exist if it is 
non-empty.
         */
        protected final SortedVectorByNumber[] priorities;
-       protected final Map allRequestsByClientRequest;
        protected final List /* <BaseSendableGet> */ recentSuccesses;
        protected transient ClientRequestScheduler sched;
        /** Transient even for persistent scheduler. */
@@ -65,10 +64,9 @@

        abstract boolean persistent();

-       protected ClientRequestSchedulerBase(boolean forInserts, boolean 
forSSKs, Map allRequestsByClientRequest, List recentSuccesses) {
+       protected ClientRequestSchedulerBase(boolean forInserts, boolean 
forSSKs, List recentSuccesses) {
                this.isInsertScheduler = forInserts;
                this.isSSKScheduler = forSSKs;
-               this.allRequestsByClientRequest = allRequestsByClientRequest;
                this.recentSuccesses = recentSuccesses;
                keyListeners = new HashSet<KeyListener>();
                priorities = new 
SortedVectorByNumber[RequestStarter.NUMBER_OF_PRIORITY_CLASSES];
@@ -97,23 +95,9 @@
        }

        protected void addToRequestsByClientRequest(ClientRequester 
clientRequest, SendableRequest req, ObjectContainer container) {
-               synchronized(sched) {
-               Set v = (Set) 
allRequestsByClientRequest.get(req.getClientRequest());
-               if(persistent())
-                       container.activate(v, 1);
-               if(v == null) {
-                       v = makeSetForAllRequestsByClientRequest(container);
-                       allRequestsByClientRequest.put(req.getClientRequest(), 
v);
-               }
-               v.add(req);
-               int vSize = v.size();
-               if(persistent())
-                       container.deactivate(v, 1);
-               if(logMINOR)
-                       Logger.minor(this, "Added to allRequestsByClientRequest 
for "+clientRequest+" size now "+v.size());
-               }
+               clientRequest.addToRequests(req, container);
        }
-
+       
        synchronized void addToGrabArray(short priorityClass, int retryCount, 
int rc, RequestClient client, ClientRequester cr, SendableRequest req, 
RandomSource random, ObjectContainer container) {
                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)");
@@ -161,6 +145,14 @@
                return Math.max(0, retryCount-MIN_RETRY_COUNT);
        }

+       protected SendableRequest[] getSendableRequests(ClientRequester 
request, ObjectContainer container) {
+               return request.getSendableRequests(container);
+       }
+
+       void removeFromAllRequestsByClientRequest(SendableRequest req, 
ClientRequester cr, boolean dontComplain, ObjectContainer container) {
+               cr.removeFromRequests(req, container, dontComplain);
+       }
+       
        public void reregisterAll(ClientRequester request, RandomSource random, 
RequestScheduler lock, ObjectContainer container, ClientContext context) {
                SendableRequest[] reqs = getSendableRequests(request, 
container);
                if(reqs == null) return;
@@ -177,19 +169,6 @@
                }
        }

-       private SendableRequest[] getSendableRequests(ClientRequester request, 
ObjectContainer container) {
-               synchronized(sched) {
-                       Set h = (Set) allRequestsByClientRequest.get(request);
-                       if(h == null) return null;
-                       if(persistent())
-                               container.activate(h, 1);
-                       SendableRequest[] reqs = (SendableRequest[]) 
h.toArray(new SendableRequest[h.size()]);
-                       if(persistent())
-                               container.deactivate(h, 1);
-                       return reqs;
-               }
-       }
-
        public void succeeded(BaseSendableGet succeeded, ObjectContainer 
container) {
                if(isInsertScheduler) return;
                if(persistent()) {
@@ -203,30 +182,6 @@
                                recentSuccesses.remove(0);
        }

-       protected void removeFromAllRequestsByClientRequest(SendableRequest 
req, ClientRequester cr, boolean dontComplain, ObjectContainer container) {
-               synchronized(sched) {
-               if(logMINOR)
-                       Logger.minor(this, "Removing from 
allRequestsByClientRequest: "+req+ " for "+cr);
-                       Set v = (Set) allRequestsByClientRequest.get(cr);
-                       if(v == null) {
-                               if(!dontComplain)
-                                       Logger.error(this, "No HashSet 
registered for "+cr+" for "+req);
-                       } else {
-                               if(persistent())
-                                       container.activate(v, 1);
-                               boolean removed = v.remove(req);
-                               int vSize = v.size();
-                               if(v.isEmpty())
-                                       allRequestsByClientRequest.remove(cr);
-                               else {
-                                       if(persistent())
-                                               container.deactivate(v, 1);
-                               }
-                               if(logMINOR) Logger.minor(this, (removed ? "" : 
"Not ") + "Removed "+req+" from HashSet for "+cr+" which now has "+vSize+" 
elements");
-                       }
-               }
-       }
-
        public synchronized void addPendingKeys(KeyListener listener) {
                keyListeners.add(listener);
                System.out.println("Added pending keys to "+this+" : size now 
"+keyListeners.size()+" : "+listener);

Modified: 
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerCore.java
===================================================================
--- 
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerCore.java  
    2008-08-28 21:41:39 UTC (rev 22204)
+++ 
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerCore.java  
    2008-08-28 23:04:34 UTC (rev 22205)
@@ -98,7 +98,7 @@
        }

        ClientRequestSchedulerCore(Node node, boolean forInserts, boolean 
forSSKs, ObjectContainer selectorContainer, long cooldownTime) {
-               super(forInserts, forSSKs, 
selectorContainer.ext().collections().newHashMap(32), 
selectorContainer.ext().collections().newLinkedList());
+               super(forInserts, forSSKs, 
selectorContainer.ext().collections().newLinkedList());
                this.nodeDBHandle = node.nodeDBHandle;
                if(!forInserts) {
                        this.persistentCooldownQueue = new 
PersistentCooldownQueue();
@@ -112,11 +112,8 @@
        private void onStarted(ObjectContainer container, long cooldownTime, 
ClientRequestScheduler sched, ClientContext context) {
                super.onStarted();
                System.err.println("insert scheduler: "+isInsertScheduler);
-               if(allRequestsByClientRequest == null)
-                       System.err.println("allRequestsByClientRequest is 
null");
                if(recentSuccesses == null)
                        System.err.println("recentSuccesses is null");
-               ((Db4oMap)allRequestsByClientRequest).activationDepth(1);
                ((Db4oList)recentSuccesses).activationDepth(1);
                if(!isInsertScheduler) {
                        persistentCooldownQueue.setCooldownTime(cooldownTime);

Modified: 
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerNonPersistent.java
===================================================================
--- 
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerNonPersistent.java
     2008-08-28 21:41:39 UTC (rev 22204)
+++ 
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerNonPersistent.java
     2008-08-28 23:04:34 UTC (rev 22205)
@@ -12,6 +12,7 @@
 import com.db4o.ObjectContainer;

 import freenet.keys.Key;
+import freenet.node.SendableRequest;
 import freenet.support.Logger;

 /**
@@ -36,8 +37,11 @@
         * itself. */
        protected final Map /* <Key, SendableGet[]> */ pendingKeys;

+       protected final Map allRequestsByClientRequest;
+       
        ClientRequestSchedulerNonPersistent(ClientRequestScheduler sched, 
boolean forInserts, boolean forSSKs) {
-               super(forInserts, forSSKs, new HashMap(), new LinkedList());
+               super(forInserts, forSSKs, new LinkedList());
+               allRequestsByClientRequest = new HashMap();
                this.sched = sched;
                recentSuccesses = new LinkedList();
                if(forInserts)
@@ -65,5 +69,4 @@
                else return 0;
        }

-
 }

Modified: branches/db4o/freenet/src/freenet/client/async/ClientRequester.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/async/ClientRequester.java 
2008-08-28 21:41:39 UTC (rev 22204)
+++ branches/db4o/freenet/src/freenet/client/async/ClientRequester.java 
2008-08-28 23:04:34 UTC (rev 22205)
@@ -7,6 +7,7 @@

 import freenet.keys.FreenetURI;
 import freenet.node.RequestClient;
+import freenet.node.SendableRequest;
 import freenet.support.Logger;

 /** A high level client request. A request (either fetch or put) started
@@ -22,6 +23,7 @@
        protected short priorityClass;
        protected boolean cancelled;
        protected final RequestClient client;
+       protected final SendableRequestSet requests;

        public short getPriorityClass() {
                return priorityClass;
@@ -33,6 +35,7 @@
                if(client == null)
                        throw new NullPointerException();
                hashCode = super.hashCode(); // the old object id will do fine, 
as long as we ensure it doesn't change!
+               requests = persistent() ? new PersistentSendableRequestSet() : 
new TransientSendableRequestSet();
        }

        synchronized void cancel() {
@@ -168,4 +171,25 @@
                container.activate(client, 1);
        }

+       public void addToRequests(SendableRequest req, ObjectContainer 
container) {
+               container.activate(requests, 1);
+               requests.addRequest(req, container);
+               container.deactivate(requests, 1);
+       }
+
+       public SendableRequest[] getSendableRequests(ObjectContainer container) 
{
+               container.activate(requests, 1);
+               SendableRequest[] reqs = requests.listRequests(container);
+               container.deactivate(requests, 1);
+               return reqs;
+       }
+
+       public void removeFromRequests(SendableRequest req, ObjectContainer 
container, boolean dontComplain) {
+               container.activate(requests, 1);
+               if(!requests.removeRequest(req, container) && !dontComplain) {
+                       Logger.error(this, "Not in request list for "+this+": 
"+req);
+               }
+               container.deactivate(requests, 1);
+       }
+
 }

Added: 
branches/db4o/freenet/src/freenet/client/async/PersistentSendableRequestSet.java
===================================================================
--- 
branches/db4o/freenet/src/freenet/client/async/PersistentSendableRequestSet.java
                            (rev 0)
+++ 
branches/db4o/freenet/src/freenet/client/async/PersistentSendableRequestSet.java
    2008-08-28 23:04:34 UTC (rev 22205)
@@ -0,0 +1,57 @@
+package freenet.client.async;
+
+import java.util.ArrayList;
+
+import com.db4o.ObjectContainer;
+
+import freenet.node.SendableRequest;
+
+/**
+ * Just as with SectoredRandomGrabArray, activation is a big deal, and we can
+ * safely assume that == <=> equals(). So we use a vector, and hope it doesn't
+ * get too big (it won't in the near future). Any structure that might 
conceivably
+ * call equals() is doomed, because either it requires activation (extra disk 
+ * seek), or it will cause NPEs or messy code to avoid them. One option if size
+ * becomes a problem is to have individual objects in the database for each
+ * SendableRequest; this might involve many disk seeks, so is bad.
+ * @author Matthew Toseland <toad at amphibian.dyndns.org> (0xE43DA450)
+ */
+public class PersistentSendableRequestSet implements SendableRequestSet {
+
+       private final ArrayList<SendableRequest> list;
+       
+       PersistentSendableRequestSet() {
+               list = new ArrayList();
+       }
+       
+       public synchronized boolean addRequest(SendableRequest req, 
ObjectContainer container) {
+               container.activate(list, 1);
+               int idx = find(req);
+               if(idx == -1) {
+                       list.add(req);
+                       container.set(list);
+                       return true;
+               } else return false;
+       }
+
+       private synchronized int find(SendableRequest req) {
+               for(int i=0;i<list.size();i++)
+                       if(list.get(i) == req) return i;
+               return -1;
+       }
+
+       public synchronized SendableRequest[] listRequests(ObjectContainer 
container) {
+               container.activate(list, 1);
+               return (SendableRequest[]) list.toArray(new 
SendableRequest[list.size()]);
+       }
+
+       public synchronized boolean removeRequest(SendableRequest req, 
ObjectContainer container) {
+               container.activate(list, 1);
+               int idx = find(req);
+               if(idx == -1) return false;
+               list.remove(idx);
+               container.set(list);
+               return true;
+       }
+
+}

Added: branches/db4o/freenet/src/freenet/client/async/SendableRequestSet.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/async/SendableRequestSet.java      
                        (rev 0)
+++ branches/db4o/freenet/src/freenet/client/async/SendableRequestSet.java      
2008-08-28 23:04:34 UTC (rev 22205)
@@ -0,0 +1,15 @@
+package freenet.client.async;
+
+import com.db4o.ObjectContainer;
+
+import freenet.node.SendableRequest;
+
+public interface SendableRequestSet {
+       
+       public SendableRequest[] listRequests(ObjectContainer container);
+       
+       public boolean addRequest(SendableRequest req, ObjectContainer 
container);
+       
+       public boolean removeRequest(SendableRequest req, ObjectContainer 
container);
+
+}

Added: 
branches/db4o/freenet/src/freenet/client/async/TransientSendableRequestSet.java
===================================================================
--- 
branches/db4o/freenet/src/freenet/client/async/TransientSendableRequestSet.java 
                            (rev 0)
+++ 
branches/db4o/freenet/src/freenet/client/async/TransientSendableRequestSet.java 
    2008-08-28 23:04:34 UTC (rev 22205)
@@ -0,0 +1,33 @@
+package freenet.client.async;
+
+import java.util.HashSet;
+
+import com.db4o.ObjectContainer;
+
+import freenet.node.SendableRequest;
+
+/**
+ * Since we don't need to worry about activation, we can simply use a HashSet.
+ * @author Matthew Toseland <toad at amphibian.dyndns.org> (0xE43DA450)
+ */
+public class TransientSendableRequestSet implements SendableRequestSet {
+
+       private final HashSet<SendableRequest> set;
+       
+       TransientSendableRequestSet() {
+               set = new HashSet<SendableRequest>();
+       }
+       
+       public synchronized boolean addRequest(SendableRequest req, 
ObjectContainer container) {
+               return set.add(req);
+       }
+
+       public synchronized SendableRequest[] listRequests(ObjectContainer 
container) {
+               return set.toArray(new SendableRequest[set.size()]);
+       }
+
+       public boolean removeRequest(SendableRequest req, ObjectContainer 
container) {
+               return set.remove(req);
+       }
+
+}

Modified: branches/db4o/freenet/src/freenet/support/SectoredRandomGrabArray.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/SectoredRandomGrabArray.java      
2008-08-28 21:41:39 UTC (rev 22204)
+++ branches/db4o/freenet/src/freenet/support/SectoredRandomGrabArray.java      
2008-08-28 23:04:34 UTC (rev 22205)
@@ -169,8 +169,6 @@
                                                container.activate(rga, 1);
                                        item = rga.removeRandom(excluding, 
container, context);
                                        if(firstRGA.isEmpty() && rga.isEmpty()) 
{
-                                               Object rgaClient = 
grabClients[x];
-                                               Object firstClient = 
grabClients[1-x];
                                                grabArrays = new 
RemoveRandomWithObject[0];
                                                grabClients = new Object[0];
                                                if(persistent)


Reply via email to