[freenet-cvs] r13490 - in trunk/freenet/src/freenet: io/comm node

toad at freenetproject.org toad at freenetproject.org
Fri Jun 8 17:26:51 UTC 2007


Author: toad
Date: 2007-06-08 17:26:51 +0000 (Fri, 08 Jun 2007)
New Revision: 13490

Modified:
   trunk/freenet/src/freenet/io/comm/DMT.java
   trunk/freenet/src/freenet/node/CHKInsertSender.java
   trunk/freenet/src/freenet/node/LocationManager.java
   trunk/freenet/src/freenet/node/NodeDispatcher.java
   trunk/freenet/src/freenet/node/PeerManager.java
   trunk/freenet/src/freenet/node/RequestSender.java
   trunk/freenet/src/freenet/node/SSKInsertSender.java
Log:
Include sub-message for best 3 locations seen so far but not visited.

Modified: trunk/freenet/src/freenet/io/comm/DMT.java
===================================================================
--- trunk/freenet/src/freenet/io/comm/DMT.java	2007-06-08 16:21:12 UTC (rev 13489)
+++ trunk/freenet/src/freenet/io/comm/DMT.java	2007-06-08 17:26:51 UTC (rev 13490)
@@ -96,6 +96,7 @@
 	public static final String MY_UID = "myUID";
 	public static final String PEER_LOCATIONS = "peerLocations";
 	public static final String PEER_UIDS = "peerUIDs";
+	public static final String BEST_LOCATIONS_NOT_VISITED = "bestLocationsNotVisited";
 
 	//Diagnostic
 	public static final MessageType ping = new MessageType("ping") {{
@@ -956,6 +957,36 @@
 		return msg;
 	}
 	
+	public static final Message createFNPSwapLocations(long[] uids) {
+		Message msg = new Message(FNPSwapNodeUIDs);
+		msg.set(NODE_UIDS, new ShortBuffer(Fields.longsToBytes(uids)));
+		return msg;
+	}
+	
+	// More permanent secondary messages (should perhaps be replaced by new main messages when stable)
+	
+	public static final MessageType FNPBestRoutesNotTaken = new MessageType("FNPBestRoutesNotTaken") {{
+		// Maybe this should be some sort of typed array?
+		// It's just a bunch of double's anyway.
+		addField(BEST_LOCATIONS_NOT_VISITED, ShortBuffer.class);
+	}};
+	
+	public static final Message createFNPBestRoutesNotTaken(byte[] locs) {
+		Message msg = new Message(FNPBestRoutesNotTaken);
+		msg.set(BEST_LOCATIONS_NOT_VISITED, new ShortBuffer(locs));
+		return msg;
+	}
+	
+	public static final Message createFNPBestRoutesNotTaken(double[] locs) {
+		return createFNPBestRoutesNotTaken(Fields.doublesToBytes(locs));
+	}
+	
+	public static Message createFNPBestRoutesNotTaken(Double[] doubles) {
+		double[] locs = new double[doubles.length];
+		for(int i=0;i<locs.length;i++) locs[i] = doubles[i].doubleValue();
+		return createFNPBestRoutesNotTaken(locs);
+	}
+
 	public static void init() { }
 
 }

Modified: trunk/freenet/src/freenet/node/CHKInsertSender.java
===================================================================
--- trunk/freenet/src/freenet/node/CHKInsertSender.java	2007-06-08 16:21:12 UTC (rev 13489)
+++ trunk/freenet/src/freenet/node/CHKInsertSender.java	2007-06-08 17:26:51 UTC (rev 13490)
@@ -247,7 +247,7 @@
             PeerNode next;
             // Can backtrack, so only route to nodes closer than we are to target.
             double nextValue;
-            next = node.peers.closerPeer(source, nodesRoutedTo, nodesNotIgnored, target, true, node.isAdvancedModeEnabled(), -1);
+            next = node.peers.closerPeer(source, nodesRoutedTo, nodesNotIgnored, target, true, node.isAdvancedModeEnabled(), -1, null);
             if(next != null)
                 nextValue = next.getLocation().getValue();
             else

Modified: trunk/freenet/src/freenet/node/LocationManager.java
===================================================================
--- trunk/freenet/src/freenet/node/LocationManager.java	2007-06-08 16:21:12 UTC (rev 13489)
+++ trunk/freenet/src/freenet/node/LocationManager.java	2007-06-08 17:26:51 UTC (rev 13490)
@@ -326,7 +326,7 @@
             // Send our SwapComplete
             
             Message confirm = DMT.createFNPSwapComplete(uid, myValue);
-            confirm.addSubMessage(DMT.createFNPSwapLocations(Fields.longsToBytes(extractUIDs(friendLocsAndUIDs))));
+            confirm.addSubMessage(DMT.createFNPSwapLocations(extractUIDs(friendLocsAndUIDs)));
             
             node.usm.send(pn, confirm, null);
             
@@ -438,7 +438,7 @@
                 byte[] hisHash = ((ShortBuffer)reply.getObject(DMT.HASH)).getData();
                 
                 Message confirm = DMT.createFNPSwapCommit(uid, myValue);
-                confirm.addSubMessage(DMT.createFNPSwapLocations(Fields.longsToBytes(extractUIDs(friendLocsAndUIDs))));
+                confirm.addSubMessage(DMT.createFNPSwapLocations(extractUIDs(friendLocsAndUIDs)));
 
                 filter1.clearOr();
                 MessageFilter filter3 = MessageFilter.create().setField(DMT.UID, uid).setType(DMT.FNPSwapComplete).setTimeout(TIMEOUT).setSource(pn);

Modified: trunk/freenet/src/freenet/node/NodeDispatcher.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeDispatcher.java	2007-06-08 16:21:12 UTC (rev 13489)
+++ trunk/freenet/src/freenet/node/NodeDispatcher.java	2007-06-08 17:26:51 UTC (rev 13490)
@@ -3,8 +3,11 @@
  * http://www.gnu.org/ for further details of the GPL. */
 package freenet.node;
 
+import java.util.Arrays;
+import java.util.Comparator;
 import java.util.HashSet;
 import java.util.Hashtable;
+import java.util.Vector;
 
 import freenet.io.comm.DMT;
 import freenet.io.comm.Dispatcher;
@@ -17,6 +20,7 @@
 import freenet.support.LRUQueue;
 import freenet.support.Logger;
 import freenet.support.ShortBuffer;
+import freenet.support.StringArray;
 
 /**
  * @author amphibian
@@ -347,7 +351,7 @@
 		// Forward
 		m = preForward(m, htl);
 		while(true) {
-			PeerNode next = node.peers.closerPeer(pn, ctx.routedTo, ctx.notIgnored, target, true, node.isAdvancedModeEnabled(), -1);
+			PeerNode next = node.peers.closerPeer(pn, ctx.routedTo, ctx.notIgnored, target, true, node.isAdvancedModeEnabled(), -1, null);
 			if(logMINOR) Logger.minor(this, "Next: "+next+" message: "+m);
 			if(next != null) {
 				// next is connected, or at least has been => next.getPeer() CANNOT be null.
@@ -423,6 +427,7 @@
 		short htl;
 		double nearest;
 		double best;
+		Vector notVisitedList; // List of best locations not yet visited by this request
 
 		public ProbeContext(long id, double target, double best, double nearest, short htl, short counter, PeerNode src, ProbeCallback cb) {
 			visitedPeers = new HashSet();
@@ -475,9 +480,19 @@
 				Logger.minor(this, "Probe request popped "+o);
 			}
 		}
-		return innerHandleProbeRequest(src, id, lid, target, best, nearest, htl, counter, true, true, null);
+		Message notVisited = m.getSubMessage(DMT.FNPBestRoutesNotTaken);
+		double[] locsNotVisited = null;
+		Vector notVisitedList = new Vector();
+		if(notVisited != null) {
+			locsNotVisited = Fields.bytesToDoubles(((ShortBuffer)m.getObject(DMT.BEST_LOCATIONS_NOT_VISITED)).getData());
+			for(int i=0;i<locsNotVisited.length;i++)
+				notVisitedList.add(new Double(locsNotVisited[i]));
+		}
+		return innerHandleProbeRequest(src, id, lid, target, best, nearest, htl, counter, true, true, false, null, notVisitedList);
 	}
 
+	final int MAX_LOCS_NOT_VISITED = 3;
+	
 	/**
 	 * 
 	 * @param src
@@ -491,10 +506,12 @@
 	 * @param checkRecent
 	 * @param canReject
 	 * @param cb
+	 * @param locsNotVisited 
 	 * @return
 	 */
-	private boolean innerHandleProbeRequest(PeerNode src, long id, Long lid, double target, double best, 
-			double nearest, short htl, short counter, boolean checkRecent, boolean canReject, ProbeCallback cb) {
+	private boolean innerHandleProbeRequest(PeerNode src, long id, Long lid, final double target, double best, 
+			double nearest, short htl, short counter, boolean checkRecent, boolean canReject, 
+			boolean fromRejection, ProbeCallback cb, Vector locsNotVisited) {
 		short max = node.maxHTL();
 		if(htl > max) htl = max;
 		if(htl <= 1) htl = 1;
@@ -522,6 +539,11 @@
 					recentProbeContexts.popValue();
 			}
 		}
+		if(locsNotVisited != null) {
+			if(logMINOR)
+				Logger.minor(this, "Locs not visited: "+locsNotVisited);
+		}
+		
 		// Add source
 		if(src != null) ctx.visitedPeers.add(src);
 		if(rejected) {
@@ -546,6 +568,13 @@
 		PeerNode[] peers = node.peers.connectedPeers;
 
 		double myLoc = node.getLocation();
+		for(int i=0;i<locsNotVisited.size();i++) {
+			double loc = ((Double) locsNotVisited.get(i)).doubleValue();
+			if(Math.abs(loc - myLoc) < Double.MIN_VALUE * 2) {
+				locsNotVisited.remove(i);
+				break;
+			}
+		}
 		// Update best
 
 		if(myLoc > target && myLoc < best)
@@ -589,6 +618,8 @@
 			if(src != null) {
 				// Complete
 				Message complete = DMT.createFNPProbeReply(id, target, nearest, best, counter++);
+				Message sub = DMT.createFNPBestRoutesNotTaken((Double[])locsNotVisited.toArray(new Double[locsNotVisited.size()]));
+				complete.addSubMessage(sub);
 				try {
 					src.sendAsync(complete, null, 0, null);
 				} catch (NotConnectedException e) {
@@ -606,13 +637,36 @@
 
 		while(true) {
 
-			PeerNode pn = node.peers.closerPeer(src, visited, null, target, true, false, 965);
+			Vector newBestLocs = new Vector();
+			newBestLocs.addAll(locsNotVisited);
+			PeerNode pn = node.peers.closerPeer(src, visited, null, target, true, false, 965, newBestLocs);
+			
+			Double[] locs = (Double[]) newBestLocs.toArray(new Double[newBestLocs.size()]);
+			Arrays.sort(locs, new Comparator() {
+				public int compare(Object arg0, Object arg1) {
+					double d0 = ((Double) arg0).doubleValue();
+					double d1 = ((Double) arg1).doubleValue();
+					double dist0 = PeerManager.distance(d0, target);
+					double dist1 = PeerManager.distance(d1, target);
+					if(dist0 < dist1) return -1; // best at the beginning
+					if(dist0 > dist1) return 1;
+					return 0; // should not happen
+				}
+			});
+			locsNotVisited.clear();
+			for(int i=0;i<Math.min(MAX_LOCS_NOT_VISITED, locs.length);i++)
+				locsNotVisited.add(locs[i]);
+			
+			Message sub = DMT.createFNPBestRoutesNotTaken((Double[])locsNotVisited.toArray(new Double[locsNotVisited.size()]));
+			
+			ctx.notVisitedList = locsNotVisited;
 
 			if(pn == null) {
 				// Can't complete, because some HTL left
 				// Reject: RNF
 				if(canReject) {
 					Message reject = DMT.createFNPProbeRejected(id, target, nearest, best, counter, htl, DMT.PROBE_REJECTED_RNF);
+					reject.addSubMessage(sub);
 					try {
 						src.sendAsync(reject, null, 0, null);
 					} catch (NotConnectedException e) {
@@ -629,6 +683,7 @@
 			if(src != null) {
 				Message trace =
 					DMT.createFNPProbeTrace(id, target, nearest, best, htl, counter, myLoc, node.swapIdentifier, LocationManager.extractLocs(peers, true), LocationManager.extractUIDs(peers));
+				trace.addSubMessage(sub);
 				try {
 					src.sendAsync(trace, null, 0, null);
 				} catch (NotConnectedException e1) {
@@ -638,6 +693,7 @@
 			
 			Message forwarded =
 				DMT.createFNPProbeRequest(id, target, nearest, best, htl, counter++);
+			forwarded.addSubMessage(sub);
 			try {
 				pn.sendAsync(forwarded, null, 0, null);
 				return true;
@@ -692,6 +748,8 @@
 
 		if(ctx.src != null) {
 			Message complete = DMT.createFNPProbeReply(id, target, nearest, best, counter++);
+			Message sub = m.getSubMessage(DMT.FNPBestRoutesNotTaken);
+			if(sub != null) complete.addSubMessage(sub);
 			try {
 				ctx.src.sendAsync(complete, null, 0, null);
 			} catch (NotConnectedException e) {
@@ -711,8 +769,17 @@
 		double best = m.getDouble(DMT.BEST_LOCATION);
 		double nearest = m.getDouble(DMT.NEAREST_LOCATION);
 		short counter = m.getShort(DMT.COUNTER);
+		Message notVisited = m.getSubMessage(DMT.FNPBestRoutesNotTaken);
+		double[] locsNotVisited = null;
+		if(notVisited != null) {
+			locsNotVisited = Fields.bytesToDoubles(((ShortBuffer)m.getObject(DMT.BEST_LOCATIONS_NOT_VISITED)).getData());
+		}
 		if(logMINOR)
 			Logger.minor(this, "Probe trace: "+id+ ' ' +target+ ' ' +best+ ' ' +nearest+' '+counter);
+		if(locsNotVisited != null) {
+			if(logMINOR)
+				Logger.minor(this, "Locs not visited: "+StringArray.toString(locsNotVisited));
+		}
 		// Just propagate back to source
 		ProbeContext ctx;
 		synchronized(recentProbeContexts) {
@@ -763,7 +830,15 @@
 				recentProbeContexts.popValue();
 		}
 
-		return innerHandleProbeRequest(src, id, lid, target, best, nearest, htl, counter, false, false, null);
+		Message notVisited = m.getSubMessage(DMT.FNPBestRoutesNotTaken);
+		double[] locsNotVisited = null;
+		Vector notVisitedList = new Vector();
+		if(notVisited != null) {
+			locsNotVisited = Fields.bytesToDoubles(((ShortBuffer)m.getObject(DMT.BEST_LOCATIONS_NOT_VISITED)).getData());
+			for(int i=0;i<locsNotVisited.length;i++)
+				notVisitedList.add(new Double(locsNotVisited[i]));
+		}
+		return innerHandleProbeRequest(src, id, lid, target, best, nearest, htl, counter, false, false, true, null, notVisitedList);
 	}
 
 	public void startProbe(double d, ProbeCallback cb) {
@@ -773,7 +848,7 @@
 			recentProbeRequestIDs.push(ll);
 		}
 		double nodeLoc = node.getLocation();
-		innerHandleProbeRequest(null, l, ll, d, (nodeLoc > d) ? nodeLoc : 1.0, nodeLoc, node.maxHTL(), (short)0, false, false, cb);
+		innerHandleProbeRequest(null, l, ll, d, (nodeLoc > d) ? nodeLoc : 1.0, nodeLoc, node.maxHTL(), (short)0, false, false, false, cb, new Vector());
 	}
 	
 	void start(NodeStats stats) {

Modified: trunk/freenet/src/freenet/node/PeerManager.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerManager.java	2007-06-08 16:21:12 UTC (rev 13489)
+++ trunk/freenet/src/freenet/node/PeerManager.java	2007-06-08 17:26:51 UTC (rev 13490)
@@ -537,11 +537,11 @@
      * This scans the same array 4 times.  It would be better to scan once and execute 4 callbacks...
      * For this reason the metrics are only updated if advanced mode is enabled
      */
-    public PeerNode closerPeer(PeerNode pn, HashSet routedTo, HashSet notIgnored, double loc, boolean ignoreSelf, boolean calculateMisrouting, int minVersion) {
-    	PeerNode best = closerPeerBackoff(pn, routedTo, notIgnored, loc, ignoreSelf, minVersion);
+    public PeerNode closerPeer(PeerNode pn, HashSet routedTo, HashSet notIgnored, double loc, boolean ignoreSelf, boolean calculateMisrouting, int minVersion, Vector addUnpickedLocsTo) {
+    	PeerNode best = closerPeerBackoff(pn, routedTo, notIgnored, loc, ignoreSelf, minVersion, addUnpickedLocsTo);
     		
     	if (calculateMisrouting) {
-    		PeerNode nbo = _closerPeer(pn, routedTo, notIgnored, loc, ignoreSelf, true, minVersion);
+    		PeerNode nbo = _closerPeer(pn, routedTo, notIgnored, loc, ignoreSelf, true, minVersion, null);
     		if(nbo != null) {
     			node.nodeStats.routingMissDistance.report(distance(best, nbo.getLocation().getValue()));
     			int numberOfConnected = getPeerNodeStatusSize(PEER_NODE_STATUS_CONNECTED);
@@ -554,10 +554,10 @@
     	return best;
     }
 	    
-    private PeerNode closerPeerBackoff(PeerNode pn, HashSet routedTo, HashSet notIgnored, double loc, boolean ignoreSelf, int minVersion) {
-    	PeerNode best = _closerPeer(pn, routedTo, notIgnored, loc, ignoreSelf, false, minVersion);
+    private PeerNode closerPeerBackoff(PeerNode pn, HashSet routedTo, HashSet notIgnored, double loc, boolean ignoreSelf, int minVersion, Vector addUnpickedLocsTo) {
+    	PeerNode best = _closerPeer(pn, routedTo, notIgnored, loc, ignoreSelf, false, minVersion, addUnpickedLocsTo);
     	if(best == null) {
-    		best = _closerPeer(pn, routedTo, notIgnored, loc, ignoreSelf, true, minVersion);
+    		best = _closerPeer(pn, routedTo, notIgnored, loc, ignoreSelf, true, minVersion, addUnpickedLocsTo);
     	}
     	return best;
 	}
@@ -565,8 +565,10 @@
 	/**
      * Find the peer, if any, which is closer to the target location
      * than we are, and is not included in the provided set.
+	 * @param addUnpickedLocsTo Add all locations we didn't choose which we could have routed to to 
+	 * this array. Remove the location of the peer we pick from it.
      */
-    private PeerNode _closerPeer(PeerNode pn, HashSet routedTo, HashSet notIgnored, double loc, boolean ignoreSelf, boolean ignoreBackedOff, int minVersion) {
+    private PeerNode _closerPeer(PeerNode pn, HashSet routedTo, HashSet notIgnored, double loc, boolean ignoreSelf, boolean ignoreBackedOff, int minVersion, Vector addUnpickedLocsTo) {
         PeerNode[] peers;  
         synchronized (this) {
 			peers = connectedPeers;
@@ -577,6 +579,7 @@
         if(!ignoreSelf)
             maxDiff = distance(node.lm.getLocation().getValue(), loc);
         PeerNode best = null;
+        double bestLoc = -2;
         int count = 0;
         for(int i=0;i<peers.length;i++) {
             PeerNode p = peers[i];
@@ -608,11 +611,20 @@
             	continue;
             }
             if(diff < bestDiff) {
+            	if(bestLoc > 0 && addUnpickedLocsTo != null) {
+            		Double d = new Double(bestLoc);
+            		// Here we can directly compare double's because they aren't processed in any way, and are finite and (probably) nonzero.
+            		if(!addUnpickedLocsTo.contains(d))
+            			addUnpickedLocsTo.add(d);
+            	}
+            	bestLoc = loc;
                 best = p;
                 bestDiff = diff;
                 if(logMINOR) Logger.minor(this, "New best: "+diff+" ("+p.getLocation().getValue()+" for "+p.getPeer());
             }
         }
+        if(addUnpickedLocsTo != null)
+        	addUnpickedLocsTo.remove(new Double(bestLoc));
         return best;
     }
 

Modified: trunk/freenet/src/freenet/node/RequestSender.java
===================================================================
--- trunk/freenet/src/freenet/node/RequestSender.java	2007-06-08 16:21:12 UTC (rev 13489)
+++ trunk/freenet/src/freenet/node/RequestSender.java	2007-06-08 17:26:51 UTC (rev 13490)
@@ -132,7 +132,7 @@
             // Route it
             PeerNode next;
             double nextValue;
-            next = node.peers.closerPeer(source, nodesRoutedTo, nodesNotIgnored, target, true, node.isAdvancedModeEnabled(), -1);
+            next = node.peers.closerPeer(source, nodesRoutedTo, nodesNotIgnored, target, true, node.isAdvancedModeEnabled(), -1, null);
             if(next != null)
                 nextValue = next.getLocation().getValue();
             else

Modified: trunk/freenet/src/freenet/node/SSKInsertSender.java
===================================================================
--- trunk/freenet/src/freenet/node/SSKInsertSender.java	2007-06-08 16:21:12 UTC (rev 13489)
+++ trunk/freenet/src/freenet/node/SSKInsertSender.java	2007-06-08 17:26:51 UTC (rev 13490)
@@ -137,7 +137,7 @@
             // Can backtrack, so only route to nodes closer than we are to target.
             double nextValue;
             synchronized(node.peers) {
-                next = node.peers.closerPeer(source, nodesRoutedTo, nodesNotIgnored, target, true, node.isAdvancedModeEnabled(), -1);
+                next = node.peers.closerPeer(source, nodesRoutedTo, nodesNotIgnored, target, true, node.isAdvancedModeEnabled(), -1, null);
                 if(next != null)
                     nextValue = next.getLocation().getValue();
                 else




More information about the cvs mailing list