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)