[freenet-cvs] r17483 - trunk/freenet/src/freenet/client/async

toad at freenetproject.org toad at freenetproject.org
Sat Feb 2 23:00:05 UTC 2008


Author: toad
Date: 2008-02-02 23:00:04 +0000 (Sat, 02 Feb 2008)
New Revision: 17483

Added:
   trunk/freenet/src/freenet/client/async/OfferedKeysList.java
Modified:
   trunk/freenet/src/freenet/client/async/ClientRequestScheduler.java
Log:
Beginnings of client layer support

Modified: trunk/freenet/src/freenet/client/async/ClientRequestScheduler.java
===================================================================
--- trunk/freenet/src/freenet/client/async/ClientRequestScheduler.java	2008-02-02 21:54:52 UTC (rev 17482)
+++ trunk/freenet/src/freenet/client/async/ClientRequestScheduler.java	2008-02-02 23:00:04 UTC (rev 17483)
@@ -86,6 +86,7 @@
 	 * To speed up fetching, a RGA or SVBN must only exist if it is non-empty.
 	 */
 	private final SortedVectorByNumber[] priorities;
+	private final OfferedKeysList[] offeredKeys;
 	// we have one for inserts and one for requests
 	final boolean isInsertScheduler;
 	final boolean isSSKScheduler;
@@ -178,6 +179,13 @@
 				new PrioritySchedulerCallback(this));
 		
 		this.choosenPriorityScheduler = sc.getString(name+"_priority_policy");
+		if(!forInserts) {
+			offeredKeys = new OfferedKeysList[RequestStarter.NUMBER_OF_PRIORITY_CLASSES];
+			for(short i=0;i<RequestStarter.NUMBER_OF_PRIORITY_CLASSES;i++)
+				offeredKeys[i] = new OfferedKeysList(node.clientCore, random, i);
+		} else {
+			offeredKeys = null;
+		}
 		logMINOR = Logger.shouldLog(Logger.MINOR, this);
 	}
 	
@@ -376,6 +384,11 @@
 				Logger.minor(this, "Nothing to do");
 			return null;
 		}
+		boolean tryOfferedKeys = (offeredKeys != null) && node.random.nextBoolean();
+		if(tryOfferedKeys) {
+			if(!offeredKeys[choosenPriorityClass].isEmpty())
+				return offeredKeys[choosenPriorityClass];
+		}
 		SortedVectorByNumber s = priorities[choosenPriorityClass];
 		if(s != null){
 			while(true) {

Added: trunk/freenet/src/freenet/client/async/OfferedKeysList.java
===================================================================
--- trunk/freenet/src/freenet/client/async/OfferedKeysList.java	                        (rev 0)
+++ trunk/freenet/src/freenet/client/async/OfferedKeysList.java	2008-02-02 23:00:04 UTC (rev 17483)
@@ -0,0 +1,123 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+package freenet.client.async;
+
+import java.util.HashSet;
+import java.util.Vector;
+
+import freenet.crypt.RandomSource;
+import freenet.keys.ClientKey;
+import freenet.node.LowLevelGetException;
+import freenet.node.NodeClientCore;
+import freenet.node.RequestScheduler;
+import freenet.node.SendableRequest;
+import freenet.support.Logger;
+
+/**
+ * All the keys at a given priority which we have received key offers from other nodes for.
+ * 
+ * This list needs to be kept up to date when:
+ * - A request is removed.
+ * - A request's priority changes.
+ * - A key is found.
+ * - A node disconnects or restarts (through the BlockOffer objects on the FailureTable).
+ * 
+ * And of course, when an offer is received, we need to add an element.
+ * 
+ * @author toad
+ *
+ */
+public class OfferedKeysList extends SendableRequest {
+
+	private final HashSet keys;
+	// FIXME is there any way to avoid the O(n) shuffling penalty here?
+	private final Vector keysList;
+	private static boolean logMINOR;
+	private final RandomSource random;
+	private final short priorityClass;
+	private final NodeClientCore core;
+	
+	OfferedKeysList(NodeClientCore core, RandomSource random, short priorityClass) {
+		this.keys = new HashSet();
+		this.keysList = new Vector();
+		this.random = random;
+		this.priorityClass = priorityClass;
+		this.core = core;
+		logMINOR = Logger.shouldLog(Logger.MINOR, this);
+	}
+	
+	/** Called when a key is found. */
+	public synchronized void onFoundKey(ClientKey key) {
+		logMINOR = Logger.shouldLog(Logger.MINOR, this);
+		if(logMINOR) Logger.minor(this, "Found "+key+" , removing it");
+		keys.remove(key);
+		keysList.remove(key);
+	}
+	
+	/** Called when there are no more valid offers for a key */
+	public synchronized void onNoOffers(ClientKey key) {
+		logMINOR = Logger.shouldLog(Logger.MINOR, this);
+		if(logMINOR) Logger.minor(this, "No offers for "+key+" , removing it");
+		keys.remove(key);
+		keysList.remove(key);
+	}
+
+	public synchronized boolean isEmpty() {
+		return keys.isEmpty();
+	}
+
+	public Object[] allKeys() {
+		// Not supported.
+		throw new UnsupportedOperationException();
+	}
+
+	public Object chooseKey() {
+		// Pick a random key
+		if(keysList.isEmpty()) return null;
+		Object o = keysList.remove(random.nextInt(keysList.size()));
+		keys.remove(o);
+		return o;
+	}
+
+	public Object getClient() {
+		return this;
+	}
+
+	public ClientRequester getClientRequest() {
+		// FIXME is this safe?
+		return null;
+	}
+
+	public short getPriorityClass() {
+		return priorityClass;
+	}
+
+	public int getRetryCount() {
+		return 0; // All keys have equal chance even if they've been tried before.
+	}
+
+	public void internalError(Object keyNum, Throwable t) {
+		Logger.error(this, "Internal error: "+t, t);
+	}
+	
+	public boolean send(NodeClientCore node, RequestScheduler sched, Object keyNum) {
+		ClientKey key = (ClientKey) keyNum;
+		try {
+			core.realGetKey(key, false, true, // if it's not cached it won't propagate FIXME support =false??
+					false);
+		} catch (LowLevelGetException e) {
+			Logger.minor(this, "Caught low level get exception "+e, e);
+		}
+		return true;
+	}
+
+	public boolean canRemove() {
+		return false;
+	}
+
+	public boolean isCancelled() {
+		return false;
+	}
+
+}




More information about the cvs mailing list