Author: toad
Date: 2008-05-21 12:15:00 +0000 (Wed, 21 May 2008)
New Revision: 20005
Modified:
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerBase.java
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerCore.java
Log:
Move addToGrabArray to base class
Modified:
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerBase.java
===================================================================
---
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerBase.java
2008-05-21 09:17:31 UTC (rev 20004)
+++
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerBase.java
2008-05-21 12:15:00 UTC (rev 20005)
@@ -5,10 +5,16 @@
import java.util.Map;
+import freenet.crypt.RandomSource;
import freenet.keys.ClientKey;
import freenet.keys.Key;
+import freenet.node.RequestStarter;
import freenet.node.SendableGet;
+import freenet.node.SendableRequest;
import freenet.support.Logger;
+import freenet.support.SectoredRandomGrabArrayWithInt;
+import freenet.support.SectoredRandomGrabArrayWithObject;
+import freenet.support.SortedVectorByNumber;
/**
* Base class for ClientRequestSchedulerCore and
ClientRequestSchedulerNonPersistent,
@@ -18,14 +24,32 @@
*/
public abstract class ClientRequestSchedulerBase {
+ /** Minimum number of retries at which we start to hold it against a
request.
+ * See the comments on fixRetryCount; we don't want many untried
requests to prevent
+ * us from trying requests which have only been tried once (e.g. USK
checkers), from
+ * other clients (and we DO want retries to take precedence over client
round robin IF
+ * the request has been tried many times already). */
+ private static final int MIN_RETRY_COUNT = 3;
+
private static boolean logMINOR;
/** All pending gets by key. Used to automatically satisfy pending
requests when either the key is fetched by
* an overlapping request, or it is fetched by a request from another
node. Operations on this are synchronized on
* itself. */
protected final Map /* <Key, SendableGet[]> */ pendingKeys;
+ /**
+ * Structure:
+ * array (by priority) -> // one element per possible priority
+ * SortedVectorByNumber (by # retries) -> // contains each current
#retries
+ * RandomGrabArray // contains each element, allows fast
fetch-and-drop-a-random-element
+ *
+ * To speed up fetching, a RGA or SVBN must only exist if it is
non-empty.
+ */
+ protected final SortedVectorByNumber[] priorities;
+
protected ClientRequestSchedulerBase(Map pendingKeys) {
this.pendingKeys = pendingKeys;
+ priorities = new
SortedVectorByNumber[RequestStarter.NUMBER_OF_PRIORITY_CLASSES];
logMINOR = Logger.shouldLog(Logger.MINOR,
ClientRequestSchedulerBase.class);
}
@@ -184,4 +208,48 @@
else return 0;
}
+ synchronized void addToGrabArray(short priorityClass, int retryCount,
int rc, Object client, ClientRequester cr, SendableRequest req, RandomSource
random) {
+ 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)");
+ // Priority
+ SortedVectorByNumber prio = priorities[priorityClass];
+ if(prio == null) {
+ prio = new SortedVectorByNumber();
+ priorities[priorityClass] = prio;
+ }
+ // Client
+ SectoredRandomGrabArrayWithInt clientGrabber =
(SectoredRandomGrabArrayWithInt) prio.get(rc);
+ if(clientGrabber == null) {
+ clientGrabber = new
SectoredRandomGrabArrayWithInt(random, rc, true);
+ prio.add(clientGrabber);
+ if(logMINOR) Logger.minor(this, "Registering retry
count "+rc+" with prioclass "+priorityClass+" on "+clientGrabber+" for "+prio);
+ }
+ // SectoredRandomGrabArrayWithInt and lower down have
hierarchical locking and auto-remove.
+ // To avoid a race condition it is essential to mirror that
here.
+ synchronized(clientGrabber) {
+ // Request
+ SectoredRandomGrabArrayWithObject requestGrabber =
(SectoredRandomGrabArrayWithObject) clientGrabber.getGrabber(client);
+ if(requestGrabber == null) {
+ requestGrabber = new
SectoredRandomGrabArrayWithObject(client, random, true);
+ if(logMINOR)
+ Logger.minor(this, "Creating new
grabber: "+requestGrabber+" for "+client+" from "+clientGrabber+" : "+prio+" :
prio="+priorityClass+", rc="+rc);
+ clientGrabber.addGrabber(client,
requestGrabber);
+ }
+ requestGrabber.add(cr, req);
+ }
+ }
+
+ /**
+ * Mangle the retry count.
+ * Below a certain number of attempts, we don't prefer one request to
another just because
+ * it's been tried more times. The reason for this is to prevent floods
of low-retry-count
+ * requests from starving other clients' requests which need to be
retried. The other
+ * solution would be to sort by client before retry count, but that
would be excessive
+ * IMHO; we DO want to avoid rerequesting keys we've tried many times
before.
+ */
+ protected int fixRetryCount(int retryCount) {
+ return Math.max(0, retryCount-MIN_RETRY_COUNT);
+ }
+
+
}
Modified:
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerCore.java
===================================================================
---
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerCore.java
2008-05-21 09:17:31 UTC (rev 20004)
+++
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerCore.java
2008-05-21 12:15:00 UTC (rev 20005)
@@ -38,15 +38,6 @@
final boolean isInsertScheduler;
final boolean isSSKScheduler;
private final Map allRequestsByClientRequest;
- /**
- * Structure:
- * array (by priority) -> // one element per possible priority
- * SortedVectorByNumber (by # retries) -> // contains each current
#retries
- * RandomGrabArray // contains each element, allows fast
fetch-and-drop-a-random-element
- *
- * To speed up fetching, a RGA or SVBN must only exist if it is
non-empty.
- */
- private final SortedVectorByNumber[] priorities;
// FIXME cooldown queue ????
// Can we make the cooldown queue non-persistent? It refers to
SendableGet's ... so
// keeping it in memory may be a problem...
@@ -88,7 +79,6 @@
this.isSSKScheduler = forSSKs;
allRequestsByClientRequest =
selectorContainer.ext().collections().newHashMap(32);
recentSuccesses =
selectorContainer.ext().collections().newLinkedList();
- priorities = new
SortedVectorByNumber[RequestStarter.NUMBER_OF_PRIORITY_CLASSES];
}
private void onStarted() {
@@ -110,49 +100,6 @@
if(logMINOR) Logger.minor(this, "Registered "+req+" on
prioclass="+req.getPriorityClass()+", retrycount="+req.getRetryCount()+"
v.size()="+v.size());
}
- /**
- * Mangle the retry count.
- * Below a certain number of attempts, we don't prefer one request to
another just because
- * it's been tried more times. The reason for this is to prevent floods
of low-retry-count
- * requests from starving other clients' requests which need to be
retried. The other
- * solution would be to sort by client before retry count, but that
would be excessive
- * IMHO; we DO want to avoid rerequesting keys we've tried many times
before.
- */
- private int fixRetryCount(int retryCount) {
- return Math.max(0, retryCount-MIN_RETRY_COUNT);
- }
-
- synchronized void addToGrabArray(short priorityClass, int retryCount,
int rc, Object client, ClientRequester cr, SendableRequest req, RandomSource
random) {
- 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)");
- // Priority
- SortedVectorByNumber prio = priorities[priorityClass];
- if(prio == null) {
- prio = new SortedVectorByNumber();
- priorities[priorityClass] = prio;
- }
- // Client
- SectoredRandomGrabArrayWithInt clientGrabber =
(SectoredRandomGrabArrayWithInt) prio.get(rc);
- if(clientGrabber == null) {
- clientGrabber = new
SectoredRandomGrabArrayWithInt(random, rc, true);
- prio.add(clientGrabber);
- if(logMINOR) Logger.minor(this, "Registering retry
count "+rc+" with prioclass "+priorityClass+" on "+clientGrabber+" for "+prio);
- }
- // SectoredRandomGrabArrayWithInt and lower down have
hierarchical locking and auto-remove.
- // To avoid a race condition it is essential to mirror that
here.
- synchronized(clientGrabber) {
- // Request
- SectoredRandomGrabArrayWithObject requestGrabber =
(SectoredRandomGrabArrayWithObject) clientGrabber.getGrabber(client);
- if(requestGrabber == null) {
- requestGrabber = new
SectoredRandomGrabArrayWithObject(client, random, true);
- if(logMINOR)
- Logger.minor(this, "Creating new
grabber: "+requestGrabber+" for "+client+" from "+clientGrabber+" : "+prio+" :
prio="+priorityClass+", rc="+rc);
- clientGrabber.addGrabber(client,
requestGrabber);
- }
- requestGrabber.add(cr, req);
- }
- }
-
private int removeFirstAccordingToPriorities(boolean tryOfferedKeys,
int fuzz, RandomSource random, OfferedKeysList[] offeredKeys){
SortedVectorByNumber result = null;
@@ -362,13 +309,6 @@
RequestStarter.MINIMUM_PRIORITY_CLASS
};
- /** Minimum number of retries at which we start to hold it against a
request.
- * See the comments on fixRetryCount; we don't want many untried
requests to prevent
- * us from trying requests which have only been tried once (e.g. USK
checkers), from
- * other clients (and we DO want retries to take precedence over client
round robin IF
- * the request has been tried many times already). */
- private static final int MIN_RETRY_COUNT = 3;
-
public void succeeded(BaseSendableGet succeeded) {
if(isInsertScheduler) return;
synchronized(this) {