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);
- }
}
/**