Author: toad
Date: 2007-06-08 18:42:22 +0000 (Fri, 08 Jun 2007)
New Revision: 13497

Modified:
   trunk/freenet/src/freenet/node/NodeDispatcher.java
Log:
Implement limited forking on the return path for probe requests.
This is an attempt to test the lost-down-a-rabbit-hole algorithm.
Will only take effect if the next node returns a list of 
best-seen-not-visited-so-far.

Modified: trunk/freenet/src/freenet/node/NodeDispatcher.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeDispatcher.java  2007-06-08 18:17:09 UTC 
(rev 13496)
+++ trunk/freenet/src/freenet/node/NodeDispatcher.java  2007-06-08 18:42:22 UTC 
(rev 13497)
@@ -428,6 +428,7 @@
                double nearest;
                double best;
                Vector notVisitedList; // List of best locations not yet 
visited by this request
+               int forkCount;

                public ProbeContext(long id, double target, double best, double 
nearest, short htl, short counter, PeerNode src, ProbeCallback cb) {
                        visitedPeers = new HashSet();
@@ -488,10 +489,12 @@
                        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);
+               innerHandleProbeRequest(src, id, lid, target, best, nearest, 
htl, counter, true, true, false, null, notVisitedList);
+               return true;
        }

        final int MAX_LOCS_NOT_VISITED = 3;
+       final int MAX_FORKS = 2;

        /**
         * 
@@ -509,7 +512,7 @@
         * @param locsNotVisited 
         * @return
         */
-       private boolean innerHandleProbeRequest(PeerNode src, long id, Long 
lid, final double target, double best, 
+       private void 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();
@@ -554,7 +557,7 @@
                        } catch (NotConnectedException e) {
                                Logger.error(this, "Not connected rejecting a 
probe request from "+src);
                        }
-                       return true;
+                       return;
                }
                if(ctx.counter < counter) ctx.counter = counter;
                if(logMINOR)
@@ -625,7 +628,7 @@
                                } catch (NotConnectedException e) {
                                        Logger.error(this, "Not connected 
completing a probe request from "+src);
                                }
-                               return true;
+                               return;
                        } else {
                                complete("success", target, best, nearest, id, 
ctx, counter);
                        }
@@ -681,7 +684,7 @@
                                } else {
                                        complete("RNF", target, best, nearest, 
id, ctx, counter);
                                }
-                               return true;
+                               return;
                        }

                        visited.add(pn);
@@ -702,7 +705,7 @@
                        forwarded.addSubMessage(sub);
                        try {
                                pn.sendAsync(forwarded, null, 0, null);
-                               return true;
+                               return;
                        } catch (NotConnectedException e) {
                                Logger.error(this, "Could not forward message: 
disconnected: "+pn+" : "+e, e);
                                // Try another one
@@ -739,7 +742,23 @@
                short counter = m.getShort(DMT.COUNTER);
                if(logMINOR)
                        Logger.minor(this, "Probe reply: "+id+ ' ' +target+ ' ' 
+best+ ' ' +nearest);
-               // Just propagate back to source
+               
+               // New backtracking algorithm
+               
+               // Allow forking on the way home - but only if the location 
we'd fork to would be at least as good as the third best location seen but not 
visited so far.
+               
+               // First get the list of not visited so far nodes
+               
+               Message notVisited = m.getSubMessage(DMT.FNPBestRoutesNotTaken);
+               double[] locsNotVisited = null;
+               Vector notVisitedList = new Vector();
+               if(notVisited != null) {
+                       locsNotVisited = 
Fields.bytesToDoubles(((ShortBuffer)notVisited.getObject(DMT.BEST_LOCATIONS_NOT_VISITED)).getData());
+                       for(int i=0;i<locsNotVisited.length;i++)
+                               notVisitedList.add(new 
Double(locsNotVisited[i]));
+               }
+
+               // Find it
                ProbeContext ctx;
                synchronized(recentProbeContexts) {
                        ctx = (ProbeContext) recentProbeContexts.get(lid);
@@ -747,11 +766,22 @@
                                Logger.normal(this, "Could not forward probe 
reply back to source for ID "+id);
                                return false;
                        }
-                       recentProbeContexts.push(lid, ctx); // promote or add
+                       recentProbeContexts.push(lid, ctx); // promote
                        while(recentProbeContexts.size() > MAX_PROBE_CONTEXTS)
                                recentProbeContexts.popValue();
                }

+               // Maybe fork
+               
+               if(notVisitedList.size() > 0) {
+                       if(ctx.forkCount < MAX_FORKS) {
+                               ctx.forkCount++;
+                               innerHandleProbeRequest(src, id, lid, target, 
best, nearest, ctx.htl, counter, false, false, false, null, notVisitedList);
+                               return true;
+                       }
+               }
+               
+               // Just propagate back to source
                if(ctx.src != null) {
                        Message complete = DMT.createFNPProbeReply(id, target, 
nearest, best, counter++);
                        Message sub = 
m.getSubMessage(DMT.FNPBestRoutesNotTaken);
@@ -844,7 +874,8 @@
                        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);
+               innerHandleProbeRequest(src, id, lid, target, best, nearest, 
htl, counter, false, false, true, null, notVisitedList);
+               return true;
        }

        public void startProbe(double d, ProbeCallback cb) {


Reply via email to