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


Reply via email to