Author: toad
Date: 2009-04-01 18:56:06 +0000 (Wed, 01 Apr 2009)
New Revision: 26318
Modified:
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerBase.java
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerCore.java
Log:
Implement recent success preference for persistent requests
Modified:
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerBase.java
===================================================================
---
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerBase.java
2009-04-01 18:31:59 UTC (rev 26317)
+++
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerBase.java
2009-04-01 18:56:06 UTC (rev 26318)
@@ -217,7 +217,6 @@
public void succeeded(BaseSendableGet succeeded, ObjectContainer
container) {
// Do nothing.
- // FIXME: Keep a list of recently succeeded ClientRequester's.
}
public synchronized void addPendingKeys(KeyListener listener) {
Modified:
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerCore.java
===================================================================
---
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerCore.java
2009-04-01 18:31:59 UTC (rev 26317)
+++
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerCore.java
2009-04-01 18:56:06 UTC (rev 26318)
@@ -3,7 +3,9 @@
* http://www.gnu.org/ for further details of the GPL. */
package freenet.client.async;
+import java.util.ArrayList;
import java.util.HashSet;
+import java.util.LinkedList;
import java.util.List;
import com.db4o.ObjectContainer;
@@ -94,6 +96,8 @@
public final byte[] globalSalt;
+ private transient List<RandomGrabArray> recentSuccesses;
+
/**
* Fetch a ClientRequestSchedulerCore from the database, or create a
new one.
* @param node
@@ -154,6 +158,7 @@
if(!isInsertScheduler) {
keysFetching = new HashSet();
runningTransientInserts = null;
+ this.recentSuccesses = new ArrayList<RandomGrabArray>();
} else {
keysFetching = null;
runningTransientInserts = new
HashSet<RunningTransientInsert>();
@@ -482,16 +487,16 @@
}
// Check recentSuccesses
- /** FIXME:
- * This does not make sense with selecting a whole
SendableRequest
- * at a time (for persistent requests), so turn it off.
However,
- * what would make sense would be to have
recentSuccesses be a list
- * of ClientRequester's instead. This should improve
efficiency.
- * We could make it transient even for persistent
requests, although
- * we'd probably get better results if it wasn't. We
cannot use the
- * Db4o built-in deprecated activation aware
collections, because
- * they reactivate deactivated data in their commit
hooks and thus
- * cause serious problems. */
+ /** Choose a recently succeeded request.
+ * 50% chance of using a recently succeeded request, if
there is one.
+ * For transient requests, we keep a list of recently
succeeded BaseSendableGet's,
+ * because transient requests are chosen individually.
+ * But for persistent requests, we keep a list of
RandomGrabArray's, because
+ * persistent requests are chosen a whole
SendableRequest at a time.
+ *
+ * FIXME: Only replaces persistent requests with
persistent requests (of similar priority and retry count), or transient with
transient.
+ * Probably this is acceptable.
+ */
if(!req.persistent()) {
List recent = schedTransient.recentSuccesses;
SendableRequest altReq = null;
@@ -509,8 +514,8 @@
fixRetryCount(altReq.getRetryCount()) <= chosenTracker.getNumber() &&
!altReq.isEmpty(container) && altReq != req) {
// Use the recent one instead
if(logMINOR)
- Logger.minor(this, "Recently
succeeded req "+altReq+" is better, using that, reregistering chosen "+req);
- schedTransient.innerRegister(req,
random, null, null);
+ Logger.minor(this, "Recently
succeeded (transient) req "+altReq+"
(prio="+altReq.getPriorityClass(container)+" retry count
"+altReq.getRetryCount()+") is better than "+req+"
(prio="+req.getPriorityClass(container)+" retry "+req.getRetryCount()+"), using
that");
+ // Don't need to reregister, because
removeRandom doesn't actually remove!
req = altReq;
} else if(altReq != null) {
// Don't use the recent one
@@ -518,6 +523,37 @@
Logger.minor(this, "Chosen req
"+req+" is better, reregistering recently succeeded "+altReq);
recent.add(altReq);
}
+ } else {
+ RandomGrabArray altRGA = null;
+ synchronized(recentSuccesses) {
+ if(!(recentSuccesses.isEmpty() ||
random.nextBoolean())) {
+ altRGA =
recentSuccesses.remove(0);
+ }
+ }
+ container.activate(altRGA, 1);
+ if(altRGA != null &&
container.ext().isStored(altRGA) && !altRGA.isEmpty()) {
+ container.activate(altRGA, 1);
+ if(logMINOR)
+ Logger.minor(this, "Maybe using
recently succeeded item from "+altRGA);
+ SendableRequest altReq =
(SendableRequest) altRGA.removeRandom(starter, container, context);
+ container.activate(altReq, 1);
+ if(altReq != null) {
+
if(altReq.getPriorityClass(container) <= choosenPriorityClass &&
+
fixRetryCount(altReq.getRetryCount()) <= chosenTracker.getNumber() &&
!altReq.isEmpty(container) && altReq != req) {
+ // Use the recent one
instead
+ if(logMINOR)
+
Logger.minor(this, "Recently succeeded (persistent) req "+altReq+"
(prio="+altReq.getPriorityClass(container)+" retry count
"+altReq.getRetryCount()+") is better than "+req+"
(prio="+req.getPriorityClass(container)+" retry "+req.getRetryCount()+"), using
that");
+ // Don't need to
reregister, because removeRandom doesn't actually remove!
+ req = altReq;
+ } else if(altReq != null) {
+ if(logMINOR)
+
Logger.minor(this, "Chosen (persistent) req "+req+" is better, reregistering
recently succeeded "+altRGA+" for "+altReq);
+
synchronized(recentSuccesses) {
+
recentSuccesses.add(altRGA);
+ }
+ }
+ }
+ }
}
// Now we have chosen a request.
@@ -770,5 +806,17 @@
}
}
+ public void succeeded(BaseSendableGet succeeded, ObjectContainer
container) {
+ RandomGrabArray array = succeeded.getParentGrabArray();
+ container.activate(array, 1);
+ if(array == null) return; // Unregistered already?
+ synchronized(recentSuccesses) {
+ if(recentSuccesses.contains(array)) return;
+ recentSuccesses.add(array);
+ while(recentSuccesses.size() > 8)
+ recentSuccesses.remove(0);
+ }
+ }
+
}
_______________________________________________
cvs mailing list
[email protected]
http://emu.freenetproject.org/cgi-bin/mailman/listinfo/cvs