Author: mrogers
Date: 2006-09-12 19:20:52 +0000 (Tue, 12 Sep 2006)
New Revision: 10459

Modified:
   trunk/apps/load-balancing-sims/phase6/ChkRequestHandler.java
   trunk/apps/load-balancing-sims/phase6/Node.java
   trunk/apps/load-balancing-sims/phase6/Sim.java
   trunk/apps/load-balancing-sims/phase6/messages/ChkRequest.java
   trunk/apps/load-balancing-sims/phase6/messages/RouteNotFound.java
Log:
Hops to live

Modified: trunk/apps/load-balancing-sims/phase6/ChkRequestHandler.java
===================================================================
--- trunk/apps/load-balancing-sims/phase6/ChkRequestHandler.java        
2006-09-12 19:04:31 UTC (rev 10458)
+++ trunk/apps/load-balancing-sims/phase6/ChkRequestHandler.java        
2006-09-12 19:20:52 UTC (rev 10459)
@@ -1,4 +1,4 @@
-// The state of an outstanding CHK request, stored at each node along the path
+// The state of an outstanding CHK request as stored at each node along the 
path

 import java.util.LinkedList;
 import messages.*;
@@ -12,8 +12,11 @@
        public final static int TRANSFERRING = 3;
        public final static int COMPLETED = 4;

-       public final int id; // The unique ID of the request
-       public final int key; // The requested key
+       private final int id; // The unique ID of the request
+       private final int key; // The requested key
+       private double best; // The best location seen so far
+       private int htl; // Hops to live for backtracking
+       
        private Node node; // The owner of this RequestHandler
        private Peer prev; // The previous hop of the request
        private Peer next = null; // The (current) next hop of the request
@@ -25,10 +28,20 @@
        {
                id = r.id;
                key = r.key;
+               best = r.best;
+               htl = r.htl;
                this.node = node;
                this.prev = prev;
                nexts = new LinkedList<Peer> (node.peers());
                nexts.remove (prev);
+               // If this is the best node so far, update best & reset htl
+               double target = Node.keyToLocation (key);
+               if (Node.distance (target, node.location)
+               < Node.distance (target, best)) {
+                       node.log ("resetting htl of " + this);
+                       best = node.location;
+                       htl = ChkRequest.MAX_HTL;
+               }
        }

        // Remove a peer from the list of candidates for the next hop
@@ -48,6 +61,8 @@
                        handleChkDataFound ((ChkDataFound) m);
                else if (m instanceof DataNotFound)
                        handleDataNotFound ((DataNotFound) m);
+               else if (m instanceof RouteNotFound)
+                       handleRouteNotFound ((RouteNotFound) m);
                else if (m instanceof Block) handleBlock ((Block) m);
                else if (m instanceof RouteNotFound) forwardRequest();
                else if (m instanceof RejectedLoop) forwardRequest();
@@ -57,7 +72,7 @@
        private void handleAccepted (Accepted a)
        {
                if (state != REQUEST_SENT) node.log (a + " out of order");
-               state = ACCEPTED;
+               if (state != TRANSFERRING) state = ACCEPTED;
                // Wait 60 seconds for the next hop to start sending the data
                Event.schedule (this, 60.0, FETCH_TIMEOUT, next);
        }
@@ -80,6 +95,15 @@
                state = COMPLETED;
        }

+       private void handleRouteNotFound (RouteNotFound rnf)
+       {
+               if (state != ACCEPTED) node.log (rnf + " out of order");
+               if (rnf.htl < htl) htl = rnf.htl;
+               // Use the remaining htl to try another peer
+               nexts.remove (next);
+               forwardRequest();
+       }
+       
        private void handleBlock (Block b)
        {
                if (state != TRANSFERRING) node.log (b + " out of order");
@@ -89,9 +113,9 @@
                        node.log ("forwarding " + b);
                        prev.sendMessage (b);
                }
-               // If the transfer is complete, store the data
+               // If the transfer is complete, cache the data
                if (receivedAll()) {
-                       node.storeChk (key);
+                       node.cacheChk (key);
                        if (prev == null) node.log (this + " succeeded");
                        node.chkRequestCompleted (id);
                        state = COMPLETED;
@@ -100,26 +124,42 @@

        public void forwardRequest()
        {
-               next = closestPeer();
+               // If the request has run out of hops, send DataNotFound
+               if (htl == 0) {
+                       node.log ("data not found for " + this);
+                       if (prev == null) node.log (this + " failed");
+                       else prev.sendMessage (new DataNotFound (id));
+                       node.chkRequestCompleted (id);
+                       state = COMPLETED;
+                       return;
+               }
+               // Forward the request to the best remaining peer
+               next = bestPeer();
                if (next == null) {
                        node.log ("route not found for " + this);
                        if (prev == null) node.log (this + " failed");
-                       else prev.sendMessage (new RouteNotFound (id));
+                       else prev.sendMessage (new RouteNotFound (id, htl));
                        node.chkRequestCompleted (id);
                        state = COMPLETED;
+                       return;
                }
-               else {
-                       node.log ("forwarding " + this + " to " + next.address);
-                       next.sendMessage (new ChkRequest (id, key));
-                       nexts.remove (next);
-                       state = REQUEST_SENT;
-                       // Wait 5 seconds for the next hop to accept the request
-                       Event.schedule (this, 5.0, ACCEPTED_TIMEOUT, next);
+               // Decrement htl if next node is not best so far
+               double target = Node.keyToLocation (key);
+               if (Node.distance (target, next.location)
+               > Node.distance (target, best)) {
+                       htl = node.decrementHtl (htl);
+                       node.log (this + " has htl " + htl);
                }
+               node.log ("forwarding " + this + " to " + next.address);
+               next.sendMessage (new ChkRequest (id, key, best, htl));
+               nexts.remove (next);
+               state = REQUEST_SENT;
+               // Wait 5 seconds for the next hop to accept the request
+               Event.schedule (this, 5.0, ACCEPTED_TIMEOUT, next);
        }

-       // Find the closest peer to the requested key
-       private Peer closestPeer ()
+       // Find the best remaining peer
+       private Peer bestPeer ()
        {
                double keyLoc = Node.keyToLocation (key);
                double bestDist = Double.POSITIVE_INFINITY;
@@ -137,8 +177,9 @@
        // Mark a block as received, return true if it's a duplicate
        private boolean receivedBlock (int index)
        {
-               boolean duplicate = (blockBitmap & 1 << index) != 0;
-               blockBitmap |= 1 << index;
+               int mask = 1 << index;
+               boolean duplicate = (blockBitmap & mask) != 0;
+               blockBitmap |= mask;
                return duplicate;
        }


Modified: trunk/apps/load-balancing-sims/phase6/Node.java
===================================================================
--- trunk/apps/load-balancing-sims/phase6/Node.java     2006-09-12 19:04:31 UTC 
(rev 10458)
+++ trunk/apps/load-balancing-sims/phase6/Node.java     2006-09-12 19:20:52 UTC 
(rev 10459)
@@ -70,21 +70,8 @@
                return (int) (location * Integer.MAX_VALUE);
        }

-       // Add a CHK to the cache and consider adding it to the store
-       public void storeChk (int key)
-       {
-               log ("key " + key + " added to CHK cache");
-               chkCache.put (key);
-               // Add the key to the store if this node is as close to the
-               // key's location as any of its peers
-               if (isClosest (keyToLocation (key))) {
-                       log ("key " + key + " added to CHK store");
-                       chkStore.put (key);
-               }
-       }
-       
        // Return true if this node is as close to the target as any peer
-       private boolean isClosest (double target)
+       private boolean closerThanPeers (double target)
        {
                double bestDist = Double.POSITIVE_INFINITY;
                for (Peer peer : peers.values()) {
@@ -94,6 +81,29 @@
                return distance (target, location) <= bestDist;
        }

+       // Decrement a request or insert's hops to live
+       public int decrementHtl (int htl)
+       {
+               // FIXME: don't always decrement at min/max
+               return htl - 1;
+       }
+       
+       // Add a CHK to the cache
+       public void cacheChk (int key)
+       {
+               log ("key " + key + " added to CHK cache");
+               chkCache.put (key);
+       }
+       
+       // Consider adding a CHK to the store
+       public void storeChk (int key)
+       {
+               if (closerThanPeers (keyToLocation (key))) {
+                       log ("key " + key + " added to CHK store");
+                       chkStore.put (key);
+               }
+       }
+       
        // Called by Peer
        public void startTimer()
        {
@@ -195,7 +205,7 @@
        // Event callback
        private void generateRequest (int key)
        {
-               ChkRequest r = new ChkRequest (key);
+               ChkRequest r = new ChkRequest (key, location);
                log ("generating " + r);
                handleChkRequest (r, null);
        }

Modified: trunk/apps/load-balancing-sims/phase6/Sim.java
===================================================================
--- trunk/apps/load-balancing-sims/phase6/Sim.java      2006-09-12 19:04:31 UTC 
(rev 10458)
+++ trunk/apps/load-balancing-sims/phase6/Sim.java      2006-09-12 19:20:52 UTC 
(rev 10459)
@@ -17,20 +17,17 @@
                Node n1 = new Node (txSpeed, rxSpeed);
                Node n2 = new Node (txSpeed, rxSpeed);
                Node n3 = new Node (txSpeed, rxSpeed);
+               Node n4 = new Node (txSpeed, rxSpeed);

-               n0.connectBothWays (n1, 0.001);
-               n1.connectBothWays (n2, 0.001);
-               n1.connectBothWays (n3, 0.001);
-               n2.connectBothWays (n3, 0.001);
+               n0.connectBothWays (n1, 0.1);
+               n1.connectBothWays (n2, 0.1);
+               n1.connectBothWays (n3, 0.1);
+               n2.connectBothWays (n3, 0.1);
+               n3.connectBothWays (n4, 0.1);

-               // DEBUG
-               n2.faulty = true;
-               
-               for (int i = 0; i < 4; i++) {
+               for (int i = 0; i < 2; i++) {
                        int key = Node.locationToKey (Math.random());
-                       // Half the requests will succeed, half will time out
-                       if (i % 2 == 0) n3.storeChk (key);
-                       else n2.storeChk (key);
+                       if (i % 2 == 0) n4.cacheChk (key);
                        Event.schedule (n0, 0.0, Node.GENERATE_REQUEST, key);
                }


Modified: trunk/apps/load-balancing-sims/phase6/messages/ChkRequest.java
===================================================================
--- trunk/apps/load-balancing-sims/phase6/messages/ChkRequest.java      
2006-09-12 19:04:31 UTC (rev 10458)
+++ trunk/apps/load-balancing-sims/phase6/messages/ChkRequest.java      
2006-09-12 19:20:52 UTC (rev 10459)
@@ -2,23 +2,31 @@

 public class ChkRequest extends Message
 {
+       public final static int MAX_HTL = 5; // Maximum amount of backtracking
+       
        private static int nextId = 0;

        public final int key; // The requested key
+       public double best; // The best location seen so far
+       public int htl; // Hops to live for backtracking

        // Start a new request
-       public ChkRequest (int key)
+       public ChkRequest (int key, double location)
        {
                id = nextId++;
                this.key = key;
+               best = location;
+               htl = MAX_HTL;
                size = Message.HEADER_SIZE + Message.KEY_SIZE;
        }

        // Forward a request
-       public ChkRequest (int id, int key)
+       public ChkRequest (int id, int key, double best, int htl)
        {
                this.id = id;
                this.key = key;
+               this.best = best;
+               this.htl = htl;
                size = Message.HEADER_SIZE + Message.KEY_SIZE;
        }


Modified: trunk/apps/load-balancing-sims/phase6/messages/RouteNotFound.java
===================================================================
--- trunk/apps/load-balancing-sims/phase6/messages/RouteNotFound.java   
2006-09-12 19:04:31 UTC (rev 10458)
+++ trunk/apps/load-balancing-sims/phase6/messages/RouteNotFound.java   
2006-09-12 19:20:52 UTC (rev 10459)
@@ -2,14 +2,17 @@

 public class RouteNotFound extends Message
 {
-       public RouteNotFound (int id)
+       public int htl; // Hops to live for backtracking
+       
+       public RouteNotFound (int id, int htl)
        {
                this.id = id;
+               this.htl = htl;
                size = Message.HEADER_SIZE;
        }

        public String toString()
        {
-               return new String ("route not found (" + id + ")");
+               return new String ("route not found (" + id + "," + htl + ")");
        }
 }


Reply via email to