Author: mrogers
Date: 2006-08-20 22:58:19 +0000 (Sun, 20 Aug 2006)
New Revision: 10220
Added:
trunk/apps/load-balancing-sims/phase6/
trunk/apps/load-balancing-sims/phase6/CongestionWindow.java
trunk/apps/load-balancing-sims/phase6/Node.java
trunk/apps/load-balancing-sims/phase6/Packet.java
trunk/apps/load-balancing-sims/phase6/Peer.java
trunk/apps/load-balancing-sims/phase6/Sim.java
trunk/apps/load-balancing-sims/phase6/messages/
trunk/apps/load-balancing-sims/phase6/messages/Message.java
trunk/apps/load-balancing-sims/phase6/messages/Request.java
trunk/apps/load-balancing-sims/phase6/messages/Response.java
trunk/apps/load-balancing-sims/phase6/messages/RouteNotFound.java
Removed:
trunk/apps/load-balancing-sims/phase6/Ack.java
trunk/apps/load-balancing-sims/phase6/CongestionWindow.java
trunk/apps/load-balancing-sims/phase6/Message.java
trunk/apps/load-balancing-sims/phase6/Node.java
trunk/apps/load-balancing-sims/phase6/Packet.java
trunk/apps/load-balancing-sims/phase6/Peer.java
trunk/apps/load-balancing-sims/phase6/Request.java
trunk/apps/load-balancing-sims/phase6/Response.java
trunk/apps/load-balancing-sims/phase6/RouteNotFound.java
trunk/apps/load-balancing-sims/phase6/Sim.java
Modified:
trunk/apps/load-balancing-sims/phase6/RequestState.java
Log:
Moved Messages into a separate package in preparation for FNP
Copied: trunk/apps/load-balancing-sims/phase6 (from rev 9966,
trunk/apps/load-balancing-sims/phase5-coalescing)
Deleted: trunk/apps/load-balancing-sims/phase6/Ack.java
===================================================================
--- trunk/apps/load-balancing-sims/phase5-coalescing/Ack.java 2006-08-08
14:39:02 UTC (rev 9966)
+++ trunk/apps/load-balancing-sims/phase6/Ack.java 2006-08-20 22:58:19 UTC
(rev 10220)
@@ -1,13 +0,0 @@
-// Tell the sender how long each ack was delayed so it can measure the RTT
-
-class Ack
-{
- public final int seq; // Sequence number of an acked packet
- public final double delay; // Seconds the ack was delayed for coalescing
-
- public Ack (int seq, double delay)
- {
- this.seq = seq;
- this.delay = delay;
- }
-}
Deleted: trunk/apps/load-balancing-sims/phase6/CongestionWindow.java
===================================================================
--- trunk/apps/load-balancing-sims/phase5-coalescing/CongestionWindow.java
2006-08-08 14:39:02 UTC (rev 9966)
+++ trunk/apps/load-balancing-sims/phase6/CongestionWindow.java 2006-08-20
22:58:19 UTC (rev 10220)
@@ -1,74 +0,0 @@
-// AIMD congestion control
-
-class CongestionWindow
-{
- public final static int MIN_CWIND = 3000; // Minimum congestion window
- public final static int MAX_CWIND = 1000000; // Max congestion window
- public final static double ALPHA = 0.3125; // AIMD increase parameter
- public final static double BETA = 0.875; // AIMD decrease parameter
- public final static double GAMMA = 3.0; // Slow start divisor
-
- private double cwind = MIN_CWIND; // Size of window in bytes
- private int inflight = 0; // Bytes sent but not acked
- private boolean slowStart = true; // Are we in the slow start phase?
- private Peer peer; // The owner
-
- public CongestionWindow (Peer peer)
- {
- this.peer = peer;
- }
-
- public void reset()
- {
- peer.log ("congestion window decreased to " + MIN_CWIND);
- cwind = MIN_CWIND;
- peer.log ("returning to slow start");
- slowStart = true;
- }
-
- public int available()
- {
- return (int) cwind - inflight;
- }
-
- // Put bytes in flight
- public void bytesSent (int bytes)
- {
- inflight += bytes;
- peer.log (inflight + " bytes in flight");
- }
-
- // Take bytes out of flight
- public void bytesAcked (int bytes)
- {
- inflight -= bytes;
- peer.log (inflight + " bytes in flight");
- // Increase the window
- if (slowStart) cwind += bytes / GAMMA;
- else cwind += bytes * bytes * ALPHA / cwind;
- if (cwind > MAX_CWIND) cwind = MAX_CWIND;
- peer.log ("congestion window increased to " + cwind);
- }
-
- // Decrease the window when a packet is fast retransmitted
- public void fastRetransmission (double now)
- {
- peer.log (inflight + " bytes in flight");
- cwind *= BETA;
- if (cwind < MIN_CWIND) cwind = MIN_CWIND;
- peer.log ("congestion window decreased to " + cwind);
- // The slow start phase ends when the first packet is lost
- if (slowStart) {
- peer.log ("leaving slow start");
- slowStart = false;
- }
- }
-
- // Decrease the window when a packet is retransmitted due to a timeout
- public void timeout (double now)
- {
- peer.log (inflight + " bytes in flight");
- if (slowStart) fastRetransmission (now); // Leave slow start
- else reset(); // Reset the window and return to slow start
- }
-}
Copied: trunk/apps/load-balancing-sims/phase6/CongestionWindow.java (from rev
10158, trunk/apps/load-balancing-sims/phase5-coalescing/CongestionWindow.java)
===================================================================
--- trunk/apps/load-balancing-sims/phase5-coalescing/CongestionWindow.java
2006-08-17 13:28:38 UTC (rev 10158)
+++ trunk/apps/load-balancing-sims/phase6/CongestionWindow.java 2006-08-20
22:58:19 UTC (rev 10220)
@@ -0,0 +1,74 @@
+// AIMD congestion control
+
+class CongestionWindow
+{
+ public final static int MIN_CWIND = 3000; // Minimum congestion window
+ public final static int MAX_CWIND = 1000000; // Max congestion window
+ public final static double ALPHA = 0.3125; // AIMD increase parameter
+ public final static double BETA = 0.875; // AIMD decrease parameter
+ public final static double GAMMA = 3.0; // Slow start divisor
+
+ private double cwind = MIN_CWIND; // Size of window in bytes
+ private int inflight = 0; // Bytes sent but not acked
+ private boolean slowStart = true; // Are we in the slow start phase?
+ private Peer peer; // The owner
+
+ public CongestionWindow (Peer peer)
+ {
+ this.peer = peer;
+ }
+
+ public void reset()
+ {
+ peer.log ("congestion window decreased to " + MIN_CWIND);
+ cwind = MIN_CWIND;
+ peer.log ("returning to slow start");
+ slowStart = true;
+ }
+
+ public int available()
+ {
+ return (int) cwind - inflight;
+ }
+
+ // Put bytes in flight
+ public void bytesSent (int bytes)
+ {
+ inflight += bytes;
+ peer.log (inflight + " bytes in flight");
+ }
+
+ // Take bytes out of flight
+ public void bytesAcked (int bytes)
+ {
+ inflight -= bytes;
+ peer.log (inflight + " bytes in flight");
+ // Increase the window
+ if (slowStart) cwind += bytes / GAMMA;
+ else cwind += bytes * bytes * ALPHA / cwind;
+ if (cwind > MAX_CWIND) cwind = MAX_CWIND;
+ peer.log ("congestion window increased to " + cwind);
+ }
+
+ // Decrease the window when a packet is fast retransmitted
+ public void fastRetransmission (double now)
+ {
+ peer.log (inflight + " bytes in flight");
+ cwind *= BETA;
+ if (cwind < MIN_CWIND) cwind = MIN_CWIND;
+ peer.log ("congestion window decreased to " + cwind);
+ // The slow start phase ends when the first packet is lost
+ if (slowStart) {
+ peer.log ("leaving slow start");
+ slowStart = false;
+ }
+ }
+
+ // Decrease the window when a packet is retransmitted due to a timeout
+ public void timeout (double now)
+ {
+ peer.log (inflight + " bytes in flight");
+ if (slowStart) fastRetransmission (now); // Leave slow start
+ else reset(); // Reset the window and return to slow start
+ }
+}
Deleted: trunk/apps/load-balancing-sims/phase6/Message.java
===================================================================
--- trunk/apps/load-balancing-sims/phase5-coalescing/Message.java
2006-08-08 14:39:02 UTC (rev 9966)
+++ trunk/apps/load-balancing-sims/phase6/Message.java 2006-08-20 22:58:19 UTC
(rev 10220)
@@ -1,11 +0,0 @@
-// A high-level message (as opposed to a low-level packet)
-
-class Message
-{
- public final static int HEADER_SIZE = 30; // Sequence number, MAC, etc
- public final static int ID_SIZE = 16; // Size of unique request ID
- public final static int KEY_SIZE = 32; // Size of routing key
- public final static int DATA_SIZE = 1024; // Size of data block
-
- public int size; // Size in bytes
-}
Deleted: trunk/apps/load-balancing-sims/phase6/Node.java
===================================================================
--- trunk/apps/load-balancing-sims/phase5-coalescing/Node.java 2006-08-08
14:39:02 UTC (rev 9966)
+++ trunk/apps/load-balancing-sims/phase6/Node.java 2006-08-20 22:58:19 UTC
(rev 10220)
@@ -1,197 +0,0 @@
-import java.util.HashMap;
-import java.util.HashSet;
-
-class Node implements EventTarget
-{
- public final static int STORE_SIZE = 10; // Max number of keys in store
- public final static double MIN_SLEEP = 0.01; // Seconds
-
- public double location; // Routing location
- public NetworkInterface net;
- private HashMap<Integer,Peer> peers; // Look up a peer by its address
- private int requestsGenerated = 0;
- private HashSet<Integer> recentlySeenRequests; // Request IDs
- private HashMap<Integer,RequestState> outstandingRequests;
- public LruCache<Integer> cache; // Datastore containing keys
- private boolean timerRunning = false; // Is the timer running?
-
- public Node (double txSpeed, double rxSpeed)
- {
- location = Math.random();
- net = new NetworkInterface (this, txSpeed, rxSpeed);
- peers = new HashMap<Integer,Peer>();
- recentlySeenRequests = new HashSet<Integer>();
- outstandingRequests = new HashMap<Integer,RequestState>();
- cache = new LruCache<Integer> (STORE_SIZE);
- }
-
- public void connect (Node n, double latency)
- {
- Peer p = new Peer (this, n.net.address, n.location, latency);
- peers.put (n.net.address, p);
- }
-
- public void connectBothWays (Node n, double latency)
- {
- connect (n, latency);
- n.connect (this, latency);
- }
-
- // Calculate the circular distance between two locations
- public static double distance (double a, double b)
- {
- if (a > b) return Math.min (a - b, b - a + 1.0);
- else return Math.min (b - a, a - b + 1.0);
- }
-
- // Convert an integer key to a routing location
- public static double keyToLocation (int key)
- {
- return key / (double) Integer.MAX_VALUE;
- }
-
- // Convert a routing location to an integer key
- public static int locationToKey (double location)
- {
- return (int) (location * Integer.MAX_VALUE);
- }
-
- // Called by Peer
- public void startTimer()
- {
- if (timerRunning) return;
- log ("starting retransmission/coalescing timer");
- Event.schedule (this, Peer.MAX_DELAY, CHECK_TIMEOUTS, null);
- timerRunning = true;
- }
-
- // Called by NetworkInterface
- public void handlePacket (Packet packet)
- {
- Peer peer = peers.get (packet.src);
- if (peer == null) log ("unknown peer!");
- else peer.handlePacket (packet);
- }
-
- // Called by Peer
- public void handleMessage (Message m, Peer prev)
- {
- log ("received " + m);
- // FIXME: ugly
- if (m instanceof Request)
- handleRequest ((Request) m, prev);
- else if (m instanceof Response)
- handleResponse ((Response) m);
- else if (m instanceof RouteNotFound)
- handleRouteNotFound ((RouteNotFound) m);
- }
-
- private void handleRequest (Request r, Peer prev)
- {
- if (!recentlySeenRequests.add (r.id)) {
- log ("rejecting recently seen " + r);
- prev.sendMessage (new RouteNotFound (r.id));
- // Don't forward the request to prev, it's seen it
- RequestState rs = outstandingRequests.get (r.id);
- if (rs != null) rs.nexts.remove (prev);
- return;
- }
- if (cache.get (r.key)) {
- log ("key " + r.key + " found in cache");
- if (prev == null)
- log (r + " succeeded locally");
- else prev.sendMessage (new Response (r.id, r.key));
- return;
- }
- log ("key " + r.key + " not found in cache");
- forwardRequest (new RequestState (r, prev, peers.values()));
- }
-
- private void handleResponse (Response r)
- {
- RequestState rs = outstandingRequests.remove (r.id);
- if (rs == null) {
- log ("unexpected " + r);
- return;
- }
- cache.put (r.key);
- if (rs.prev == null) log (rs + " succeeded");
- else {
- log ("forwarding " + r);
- rs.prev.sendMessage (r);
- }
- }
-
- private void handleRouteNotFound (RouteNotFound r)
- {
- RequestState rs = outstandingRequests.remove (r.id);
- if (rs == null) {
- log ("unexpected route not found " + r.id);
- return;
- }
- forwardRequest (rs);
- }
-
- private void forwardRequest (RequestState rs)
- {
- Peer next = rs.closestPeer();
- if (next == null) {
- log ("route not found for " + rs);
- if (rs.prev == null)
- log (rs + " failed");
- else rs.prev.sendMessage (new RouteNotFound (rs.id));
- return;
- }
- log ("forwarding " + rs + " to " + next.address);
- next.sendMessage (new Request (rs.id, rs.key));
- rs.nexts.remove (next);
- outstandingRequests.put (rs.id, rs);
- }
-
- private void log (String message)
- {
- Event.log (net.address + " " + message);
- }
-
- // Event callback
- private void generateRequest()
- {
- if (requestsGenerated++ > 10000) return;
- // Send a request to a random location
- Request r = new Request (locationToKey (Math.random()));
- log ("generating request " + r.id);
- handleRequest (r, null);
- // Schedule the next request
- Event.schedule (this, 0.123, GENERATE_REQUEST, null);
- }
-
- // Event callback
- private void checkTimeouts()
- {
- double deadline = Double.POSITIVE_INFINITY;
- for (Peer p : peers.values())
- deadline = Math.min (deadline, p.checkTimeouts());
- if (deadline == Double.POSITIVE_INFINITY) {
- log ("stopping retransmission/coalescing timer");
- timerRunning = false;
- }
- else {
- double sleep = deadline - Event.time(); // Can be < 0
- if (sleep < MIN_SLEEP) sleep = MIN_SLEEP;
- log ("sleeping for " + sleep + " seconds");
- Event.schedule (this, sleep, CHECK_TIMEOUTS, null);
- timerRunning = true;
- }
- }
-
- // EventTarget interface
- public void handleEvent (int type, Object data)
- {
- if (type == GENERATE_REQUEST) generateRequest();
- else if (type == CHECK_TIMEOUTS) checkTimeouts();
- }
-
- // Each EventTarget class has its own event codes
- public final static int GENERATE_REQUEST = 1;
- public final static int CHECK_TIMEOUTS = 2;
-}
Copied: trunk/apps/load-balancing-sims/phase6/Node.java (from rev 10162,
trunk/apps/load-balancing-sims/phase5-coalescing/Node.java)
===================================================================
--- trunk/apps/load-balancing-sims/phase5-coalescing/Node.java 2006-08-17
15:44:21 UTC (rev 10162)
+++ trunk/apps/load-balancing-sims/phase6/Node.java 2006-08-20 22:58:19 UTC
(rev 10220)
@@ -0,0 +1,207 @@
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.ArrayList;
+import java.util.Collections;
+import messages.*;
+
+class Node implements EventTarget
+{
+ public final static int STORE_SIZE = 10; // Max number of keys in store
+ public final static double MIN_SLEEP = 0.01; // Seconds
+ public final static double SHORT_SLEEP = 0.05; // Poll the bw limiter
+
+ // Token bucket bandwidth limiter
+ public final static int BUCKET_RATE = 20000; // Bytes per second
+ public final static int BUCKET_SIZE = 40000; // Burst size in bytes
+
+ public double location; // Routing location
+ public NetworkInterface net;
+ private HashMap<Integer,Peer> peers; // Look up a peer by its address
+ private int requestsGenerated = 0;
+ private HashSet<Integer> recentlySeenRequests; // Request IDs
+ private HashMap<Integer,RequestState> outstandingRequests;
+ public LruCache<Integer> cache; // Datastore containing keys
+ public TokenBucket bandwidth; // Bandwidth limiter
+ private boolean timerRunning = false; // Is the timer running?
+
+ public Node (double txSpeed, double rxSpeed)
+ {
+ location = Math.random();
+ net = new NetworkInterface (this, txSpeed, rxSpeed);
+ peers = new HashMap<Integer,Peer>();
+ recentlySeenRequests = new HashSet<Integer>();
+ outstandingRequests = new HashMap<Integer,RequestState>();
+ cache = new LruCache<Integer> (STORE_SIZE);
+ bandwidth = new TokenBucket (BUCKET_RATE, BUCKET_SIZE);
+ }
+
+ public void connect (Node n, double latency)
+ {
+ Peer p = new Peer (this, n.net.address, n.location, latency);
+ peers.put (n.net.address, p);
+ }
+
+ public void connectBothWays (Node n, double latency)
+ {
+ connect (n, latency);
+ n.connect (this, latency);
+ }
+
+ // Calculate the circular distance between two locations
+ public static double distance (double a, double b)
+ {
+ if (a > b) return Math.min (a - b, b - a + 1.0);
+ else return Math.min (b - a, a - b + 1.0);
+ }
+
+ // Convert an integer key to a routing location
+ public static double keyToLocation (int key)
+ {
+ return key / (double) Integer.MAX_VALUE;
+ }
+
+ // Convert a routing location to an integer key
+ public static int locationToKey (double location)
+ {
+ return (int) (location * Integer.MAX_VALUE);
+ }
+
+ // Called by Peer
+ public void startTimer()
+ {
+ if (timerRunning) return;
+ log ("starting retransmission/coalescing timer");
+ Event.schedule (this, Peer.MAX_DELAY, CHECK_TIMEOUTS, null);
+ timerRunning = true;
+ }
+
+ // Called by NetworkInterface
+ public void handlePacket (Packet packet)
+ {
+ Peer peer = peers.get (packet.src);
+ if (peer == null) log ("unknown peer!");
+ else peer.handlePacket (packet);
+ }
+
+ // Called by Peer
+ public void handleMessage (Message m, Peer prev)
+ {
+ log ("received " + m);
+ // FIXME: ugly
+ if (m instanceof Request)
+ handleRequest ((Request) m, prev);
+ else if (m instanceof Response)
+ handleResponse ((Response) m);
+ else if (m instanceof RouteNotFound)
+ handleRouteNotFound ((RouteNotFound) m);
+ }
+
+ private void handleRequest (Request r, Peer prev)
+ {
+ if (!recentlySeenRequests.add (r.id)) {
+ log ("rejecting recently seen " + r);
+ prev.sendMessage (new RouteNotFound (r.id));
+ // Don't forward the request to prev, it's seen it
+ RequestState rs = outstandingRequests.get (r.id);
+ if (rs != null) rs.nexts.remove (prev);
+ return;
+ }
+ if (cache.get (r.key)) {
+ log ("key " + r.key + " found in cache");
+ if (prev == null) log (r + " succeeded locally");
+ else prev.sendMessage (new Response (r.id, r.key));
+ return;
+ }
+ log ("key " + r.key + " not found in cache");
+ forwardRequest (new RequestState (r, prev, peers.values()));
+ }
+
+ private void handleResponse (Response r)
+ {
+ RequestState rs = outstandingRequests.remove (r.id);
+ if (rs == null) {
+ log ("unexpected " + r);
+ return;
+ }
+ cache.put (r.key);
+ if (rs.prev == null) log (rs + " succeeded");
+ else {
+ log ("forwarding " + r);
+ rs.prev.sendMessage (r);
+ }
+ }
+
+ private void handleRouteNotFound (RouteNotFound r)
+ {
+ RequestState rs = outstandingRequests.remove (r.id);
+ if (rs == null) {
+ log ("unexpected route not found " + r.id);
+ return;
+ }
+ forwardRequest (rs);
+ }
+
+ private void forwardRequest (RequestState rs)
+ {
+ Peer next = rs.closestPeer();
+ if (next == null) {
+ log ("route not found for " + rs);
+ if (rs.prev == null) log (rs + " failed");
+ else rs.prev.sendMessage (new RouteNotFound (rs.id));
+ return;
+ }
+ log ("forwarding " + rs + " to " + next.address);
+ next.sendMessage (new Request (rs.id, rs.key));
+ rs.nexts.remove (next);
+ outstandingRequests.put (rs.id, rs);
+ }
+
+ private void log (String message)
+ {
+ Event.log (net.address + " " + message);
+ }
+
+ // Event callback
+ private void generateRequest()
+ {
+ for (int i = 0; i < 10000; i++) {
+ // Send a request to a random location
+ Request r = new Request (locationToKey (Math.random()));
+ log ("generating request " + r.id);
+ handleRequest (r, null);
+ }
+ }
+
+ // Event callback
+ private void checkTimeouts()
+ {
+ // Check the peers in a random order each time
+ ArrayList<Peer> shuffled = new ArrayList<Peer> (peers.values());
+ Collections.shuffle (shuffled);
+
+ double deadline = Double.POSITIVE_INFINITY;
+ for (Peer p : shuffled)
+ deadline = Math.min (deadline, p.checkTimeouts());
+ if (deadline == Double.POSITIVE_INFINITY) {
+ log ("stopping retransmission/coalescing timer");
+ timerRunning = false;
+ }
+ else {
+ double sleep = deadline - Event.time(); // Can be < 0
+ if (sleep < MIN_SLEEP) sleep = MIN_SLEEP;
+ log ("sleeping for " + sleep + " seconds");
+ Event.schedule (this, sleep, CHECK_TIMEOUTS, null);
+ }
+ }
+
+ // EventTarget interface
+ public void handleEvent (int type, Object data)
+ {
+ if (type == GENERATE_REQUEST) generateRequest();
+ else if (type == CHECK_TIMEOUTS) checkTimeouts();
+ }
+
+ // Each EventTarget class has its own event codes
+ public final static int GENERATE_REQUEST = 1;
+ public final static int CHECK_TIMEOUTS = 2;
+}
Deleted: trunk/apps/load-balancing-sims/phase6/Packet.java
===================================================================
--- trunk/apps/load-balancing-sims/phase5-coalescing/Packet.java
2006-08-08 14:39:02 UTC (rev 9966)
+++ trunk/apps/load-balancing-sims/phase6/Packet.java 2006-08-20 22:58:19 UTC
(rev 10220)
@@ -1,35 +0,0 @@
-// A low-level packet (as opposed to a high-level message)
-
-import java.util.ArrayList;
-
-class Packet
-{
- public final static int HEADER_SIZE = 80; // Including IP & UDP headers
- public final static int ACK_SIZE = 8; // Size of an ack in bytes
- public final static int MAX_SIZE = 1450; // MTU including headers
- public final static int SENSIBLE_PAYLOAD = 1000; // Coalescing
-
- public int src, dest; // Network addresses
- public int size = HEADER_SIZE; // Size in bytes, including headers
- public int seq = -1; // Data sequence number (-1 if no data)
- public ArrayList<Ack> acks = null;
- public ArrayList<Message> messages = null;
-
- public double sent; // Time at which the packet was (re) transmitted
- public double latency; // Link latency (stored here for convenience)
-
- public void addAck (Ack a)
- {
- if (acks == null) acks = new ArrayList<Ack>();
- acks.add (a);
- size += ACK_SIZE;
- }
-
- // In real life the payload would be an array of bytes
- public void addMessage (Message m)
- {
- if (messages == null) messages = new ArrayList<Message>();
- messages.add (m);
- size += m.size;
- }
-}
Copied: trunk/apps/load-balancing-sims/phase6/Packet.java (from rev 10036,
trunk/apps/load-balancing-sims/phase5-coalescing/Packet.java)
===================================================================
--- trunk/apps/load-balancing-sims/phase5-coalescing/Packet.java
2006-08-10 22:40:48 UTC (rev 10036)
+++ trunk/apps/load-balancing-sims/phase6/Packet.java 2006-08-20 22:58:19 UTC
(rev 10220)
@@ -0,0 +1,36 @@
+// A low-level packet (as opposed to a high-level message)
+
+import java.util.ArrayList;
+import messages.Message;
+
+class Packet
+{
+ public final static int HEADER_SIZE = 80; // Including IP & UDP headers
+ public final static int ACK_SIZE = 4; // Size of an ack in bytes
+ public final static int MAX_SIZE = 1450; // MTU including headers
+ public final static int SENSIBLE_PAYLOAD = 1000; // Coalescing
+
+ public int src, dest; // Network addresses
+ public int size = HEADER_SIZE; // Size in bytes, including headers
+ public int seq = -1; // Data sequence number (-1 if no data)
+ public ArrayList<Integer> acks = null;
+ public ArrayList<Message> messages = null;
+
+ public double sent; // Time at which the packet was (re) transmitted
+ public double latency; // Link latency (stored here for convenience)
+
+ public void addAck (int ack)
+ {
+ if (acks == null) acks = new ArrayList<Integer>();
+ acks.add (ack);
+ size += ACK_SIZE;
+ }
+
+ // In real life the payload would be an array of bytes
+ public void addMessage (Message m)
+ {
+ if (messages == null) messages = new ArrayList<Message>();
+ messages.add (m);
+ size += m.size;
+ }
+}
Deleted: trunk/apps/load-balancing-sims/phase6/Peer.java
===================================================================
--- trunk/apps/load-balancing-sims/phase5-coalescing/Peer.java 2006-08-08
14:39:02 UTC (rev 9966)
+++ trunk/apps/load-balancing-sims/phase6/Peer.java 2006-08-20 22:58:19 UTC
(rev 10220)
@@ -1,285 +0,0 @@
-import java.util.LinkedList;
-import java.util.Iterator;
-import java.util.HashSet;
-
-class Peer
-{
- private Node node; // The local node
- public int address; // The remote node's address
- public double location; // The remote node's routing location
- private double latency; // The latency of the connection in seconds
-
- // Retransmission parameters
- public final static double RTO = 4.0; // Retransmission timeout in RTTs
- public final static double FRTO = 1.5; // Fast retx timeout in RTTs
- public final static double RTT_DECAY = 0.9; // Exp moving average
-
- // Coalescing
- public final static double MAX_DELAY = 0.1; // Coalescing delay, seconds
-
- // Out-of-order delivery with eventual detection of missing packets
- public final static int SEQ_RANGE = 1000;
-
- // Token bucket bandwidth limiter
- public final static int BUCKET_RATE = 2000; // Bytes per second
- public final static int BUCKET_SIZE = 4000; // Burst size in bytes
-
- // Sender state
- private double rtt = 5.0; // Estimated round-trip time in seconds
- private int txSeq = 0; // Sequence number of next outgoing data packet
- private int txMaxSeq = SEQ_RANGE - 1; // Highest sequence number
- private LinkedList<Packet> txBuffer; // Retransmission buffer
- private LinkedList<Deadline<Message>> msgQueue; // Outgoing messages
- private int msgQueueSize = 0; // Size of message queue in bytes
- private LinkedList<Deadline<Integer>> ackQueue; // Outgoing acks
- private int ackQueueSize = 0; // Size of ack queue in bytes
- private CongestionWindow window; // AIMD congestion window
- private double lastTransmission = 0.0; // Clock time
- private TokenBucket bandwidth; // Token bucket bandwidth limiter
-
- // Receiver state
- private HashSet<Integer> rxDupe; // Detect duplicates by sequence number
- private int rxSeq = 0; // Sequence number of next in-order incoming pkt
-
- public Peer (Node node, int address, double location, double latency)
- {
- this.node = node;
- this.address = address;
- this.location = location;
- this.latency = latency;
- txBuffer = new LinkedList<Packet>();
- msgQueue = new LinkedList<Deadline<Message>>();
- ackQueue = new LinkedList<Deadline<Integer>>();
- window = new CongestionWindow (this);
- bandwidth = new TokenBucket (BUCKET_RATE, BUCKET_SIZE);
- rxDupe = new HashSet<Integer>();
- }
-
- // Queue a message for transmission
- public void sendMessage (Message m)
- {
- log (m + " added to message queue");
- // Warning: until token-passing is implemented the length of
- // the message queue is unlimited
- double now = Event.time();
- msgQueue.add (new Deadline<Message> (m, now + MAX_DELAY));
- msgQueueSize += m.size;
- log (msgQueue.size() + " messages in queue");
- // Start the node's timer if necessary
- node.startTimer();
- // Send as many packets as possible
- while (send());
- }
-
- // Try to send a packet, return true if a packet was sent
- private boolean send()
- {
- if (ackQueueSize == 0 && msgQueueSize == 0) {
- log ("no messages or acks to send");
- return false;
- }
-
- // Return to slow start when the link is idle
- double now = Event.time();
- if (now - lastTransmission > RTO * rtt) window.reset();
- lastTransmission = now;
-
- // Work out how large a packet we can send
- int headersAndAcks = Packet.HEADER_SIZE + ackQueueSize;
- int payload = Packet.MAX_SIZE - headersAndAcks;
- if (payload > msgQueueSize) payload = msgQueueSize;
-
- int win = window.available() - headersAndAcks;
- if (win <= 0) log ("no room in congestion window for messages");
- if (payload > win) payload = win;
-
- int bw = bandwidth.available() - headersAndAcks;
- if (bw <= 0) log ("no bandwidth available for messages");
- if (payload > bw) payload = bw;
-
- // Delay small packets for coalescing
- if (payload < Packet.SENSIBLE_PAYLOAD && now < deadline()) {
- log ("delaying transmission of " + payload + " bytes");
- return false;
- }
-
- Packet p = new Packet();
-
- // Put all waiting acks in the packet
- for (Deadline<Integer> a : ackQueue) {
- double delay = now - (a.deadline - MAX_DELAY);
- p.addAck (new Ack (a.item, delay));
- }
- ackQueue.clear();
- ackQueueSize = 0;
-
- // Don't send sequence number n+SEQ_RANGE until sequence
- // number n has been acked - this limits the number of
- // sequence numbers the receiver must store for replay
- // detection. We must still be allowed to send acks,
- // otherwise the connection could deadlock.
-
- if (txSeq > txMaxSeq)
- log ("waiting for ack " + (txMaxSeq - SEQ_RANGE + 1));
- else {
- // Put as many messages as possible in the packet
- Iterator<Deadline<Message>> i = msgQueue.iterator();
- while (i.hasNext()) {
- Message m = i.next().item;
- if (m.size > payload) break;
- i.remove();
- msgQueueSize -= m.size;
- p.addMessage (m);
- payload -= m.size;
- }
- }
-
- // Don't send empty packets
- if (p.acks == null && p.messages == null) return false;
-
- // If the packet contains data, buffer it for retransmission
- if (p.messages != null) {
- p.seq = txSeq++;
- p.sent = now;
- txBuffer.add (p);
- window.bytesSent (p.size);
- }
-
- // Send the packet
- log ("sending packet " + p.seq + ", " + p.size + " bytes");
- node.net.send (p, address, latency);
- bandwidth.remove (p.size);
- return true;
- }
-
- private void sendAck (int seq)
- {
- log ("ack " + seq + " added to ack queue");
- double now = Event.time();
- ackQueue.add (new Deadline<Integer> (seq, now + MAX_DELAY));
- ackQueueSize += Packet.ACK_SIZE;
- log (ackQueue.size() + " acks in queue");
- // Start the node's timer if necessary
- node.startTimer();
- // Send as many packets as possible
- while (send());
- }
-
- // Called by Node when a packet arrives
- public void handlePacket (Packet p)
- {
- if (p.messages != null) handleData (p);
- if (p.acks != null) for (Ack a : p.acks) handleAck (a);
- }
-
- private void handleData (Packet p)
- {
- log ("received packet " + p.seq + ", " + p.size + " bytes");
- if (p.seq < rxSeq || rxDupe.contains (p.seq)) {
- log ("duplicate packet");
- sendAck (p.seq); // Original ack may have been lost
- }
- else if (p.seq == rxSeq) {
- log ("packet in order");
- // Find the sequence number of the next missing packet
- int was = rxSeq;
- while (rxDupe.remove (++rxSeq));
- log ("rxSeq was " + was + ", now " + rxSeq);
- // Deliver the packet
- unpack (p);
- sendAck (p.seq);
- }
- else if (p.seq < rxSeq + SEQ_RANGE) {
- log ("packet out of order - expected " + rxSeq);
- if (rxDupe.add (p.seq)) unpack (p);
- else log ("duplicate packet");
- sendAck (p.seq); // Original ack may have been lost
- }
- // This indicates a misbehaving sender - discard the packet
- else log ("warning: received " + p.seq + " before " + rxSeq);
- }
-
- private void handleAck (Ack a)
- {
- log ("received ack " + a.seq);
- double now = Event.time();
- Iterator<Packet> i = txBuffer.iterator();
- while (i.hasNext()) {
- Packet p = i.next();
- double age = now - p.sent;
- // Explicit ack
- if (p.seq == a.seq) {
- log ("packet " + p.seq + " acknowledged");
- i.remove();
- // Update the congestion window
- window.bytesAcked (p.size);
- // Update the average round-trip time
- rtt *= RTT_DECAY;
- rtt += (age - a.delay) * (1.0 - RTT_DECAY);
- log ("ack delay " + a.delay);
- log ("round-trip time " + (age - a.delay));
- log ("average round-trip time " + rtt);
- break;
- }
- // Fast retransmission
- if (p.seq < a.seq && age > FRTO * rtt) {
- p.sent = now;
- log ("fast retransmitting packet " + p.seq);
- node.net.send (p, address, latency);
- window.fastRetransmission (now);
- }
- }
- // Recalculate the maximum sequence number
- if (txBuffer.isEmpty()) txMaxSeq = txSeq + SEQ_RANGE - 1;
- else txMaxSeq = txBuffer.peek().seq + SEQ_RANGE - 1;
- log ("maximum sequence number " + txMaxSeq);
- // Send as many packets as possible
- while (send());
- }
-
- // Remove messages from a packet and deliver them to the node
- private void unpack (Packet p)
- {
- if (p.messages == null) return;
- for (Message m : p.messages) node.handleMessage (m, this);
- }
-
- // Called by Node, returns the next coalescing or retx deadline
- public double checkTimeouts()
- {
- log ("checking timeouts");
- // Send as many packets as possible
- while (send());
- if (txBuffer.isEmpty()) {
- log ("no packets in flight");
- return deadline();
- }
- double now = Event.time();
- for (Packet p : txBuffer) {
- if (now - p.sent > RTO * rtt) {
- // Retransmission timeout
- log ("retransmitting packet " + p.seq);
- p.sent = now;
- node.net.send (p, address, latency);
- window.timeout (now);
- }
- }
- return Math.min (now + MAX_DELAY, deadline());
- }
-
- // Work out when the first ack or message needs to be sent
- private double deadline()
- {
- double deadline = Double.POSITIVE_INFINITY;
- Deadline<Integer> ack = ackQueue.peek();
- if (ack != null) deadline = ack.deadline;
- Deadline<Message> msg = msgQueue.peek();
- if (msg != null) deadline = Math.min (deadline, msg.deadline);
- return deadline;
- }
-
- public void log (String message)
- {
- Event.log (node.net.address + ":" + address + " " + message);
- }
-}
Copied: trunk/apps/load-balancing-sims/phase6/Peer.java (from rev 10165,
trunk/apps/load-balancing-sims/phase5-coalescing/Peer.java)
===================================================================
--- trunk/apps/load-balancing-sims/phase5-coalescing/Peer.java 2006-08-17
16:19:51 UTC (rev 10165)
+++ trunk/apps/load-balancing-sims/phase6/Peer.java 2006-08-20 22:58:19 UTC
(rev 10220)
@@ -0,0 +1,294 @@
+import java.util.LinkedList;
+import java.util.Iterator;
+import java.util.HashSet;
+import messages.Message;
+
+class Peer
+{
+ private Node node; // The local node
+ public int address; // The remote node's address
+ public double location; // The remote node's routing location
+ private double latency; // The latency of the connection in seconds
+
+ // Retransmission parameters
+ public final static double RTO = 4.0; // Retransmission timeout in RTTs
+ public final static double FRTO = 1.5; // Fast retx timeout in RTTs
+ public final static double RTT_DECAY = 0.9; // Exp moving average
+ public final static double LINK_IDLE = 5.0; // RTTs without a packet
+
+ // Coalescing
+ public final static double MAX_DELAY = 0.1; // Coalescing delay, seconds
+
+ // Out-of-order delivery with eventual detection of missing packets
+ public final static int SEQ_RANGE = 1000;
+
+ // Sender state
+ private double rtt = 5.0; // Estimated round-trip time in seconds
+ private int txSeq = 0; // Sequence number of next outgoing data packet
+ private int txMaxSeq = SEQ_RANGE - 1; // Highest sequence number
+ private LinkedList<Packet> txBuffer; // Retransmission buffer
+ private LinkedList<Deadline<Message>> msgQueue; // Outgoing messages
+ private int msgQueueSize = 0; // Size of message queue in bytes
+ private LinkedList<Deadline<Integer>> ackQueue; // Outgoing acks
+ private int ackQueueSize = 0; // Size of ack queue in bytes
+ private CongestionWindow window; // AIMD congestion window
+ private double lastTransmission = 0.0; // Clock time
+
+ // Receiver state
+ private HashSet<Integer> rxDupe; // Detect duplicates by sequence number
+ private int rxSeq = 0; // Sequence number of next in-order incoming pkt
+
+ public Peer (Node node, int address, double location, double latency)
+ {
+ this.node = node;
+ this.address = address;
+ this.location = location;
+ this.latency = latency;
+ txBuffer = new LinkedList<Packet>();
+ msgQueue = new LinkedList<Deadline<Message>>();
+ ackQueue = new LinkedList<Deadline<Integer>>();
+ window = new CongestionWindow (this);
+ rxDupe = new HashSet<Integer>();
+ }
+
+ // Queue a message for transmission
+ public void sendMessage (Message m)
+ {
+ log (m + " added to message queue");
+ // Warning: until token-passing is implemented the length of
+ // the message queue is unlimited
+ double now = Event.time();
+ msgQueue.add (new Deadline<Message> (m, now + MAX_DELAY));
+ msgQueueSize += m.size;
+ // Start the node's timer if necessary
+ node.startTimer();
+ // Send as many packets as possible
+ while (send());
+ }
+
+ // Try to send a packet, return true if a packet was sent
+ private boolean send()
+ {
+ if (ackQueueSize == 0 && msgQueueSize == 0) {
+ log ("no messages or acks to send");
+ return false;
+ }
+ log (ackQueue.size() + " acks in queue");
+ log (msgQueue.size() + " messages in queue");
+
+ // Return to slow start when the link is idle
+ double now = Event.time();
+ if (now - lastTransmission > LINK_IDLE * rtt) window.reset();
+ lastTransmission = now;
+
+ // Work out how large a packet we can send
+ int headersAndAcks = Packet.HEADER_SIZE + ackQueueSize;
+ int payload = Packet.MAX_SIZE - headersAndAcks;
+ if (payload > msgQueueSize) payload = msgQueueSize;
+ int win = window.available() - headersAndAcks;
+ if (payload > win) payload = win;
+ int bw = node.bandwidth.available() - headersAndAcks;
+ if (payload > bw) payload = bw;
+
+ // Delay small packets for coalescing
+ if (now < deadline (now)) {
+ log ("delaying transmission of " + payload + " bytes");
+ return false;
+ }
+
+ Packet p = new Packet();
+
+ // Put all waiting acks in the packet
+ for (Deadline<Integer> a : ackQueue) p.addAck (a.item);
+ ackQueue.clear();
+ ackQueueSize = 0;
+
+ // Don't send sequence number n+SEQ_RANGE until sequence
+ // number n has been acked - this limits the number of
+ // sequence numbers the receiver must store for replay
+ // detection. We must still be allowed to send acks,
+ // otherwise the connection could deadlock.
+
+ if (txSeq <= txMaxSeq) pack (p, payload); // OK to send data
+ else log ("waiting for ack " + (txMaxSeq - SEQ_RANGE + 1));
+
+ // Don't send empty packets
+ if (p.acks == null && p.messages == null) return false;
+
+ // If the packet contains data, buffer it for retransmission
+ if (p.messages != null) {
+ p.seq = txSeq++;
+ p.sent = now;
+ txBuffer.add (p);
+ window.bytesSent (p.size);
+ }
+
+ // Send the packet
+ log ("sending packet " + p.seq + ", " + p.size + " bytes");
+ node.net.send (p, address, latency);
+ node.bandwidth.remove (p.size);
+ return true;
+ }
+
+ private void sendAck (int seq)
+ {
+ log ("ack " + seq + " added to ack queue");
+ double now = Event.time();
+ ackQueue.add (new Deadline<Integer> (seq, now + MAX_DELAY));
+ ackQueueSize += Packet.ACK_SIZE;
+ // Start the node's timer if necessary
+ node.startTimer();
+ // Send as many packets as possible
+ while (send());
+ }
+
+ // Called by Node when a packet arrives
+ public void handlePacket (Packet p)
+ {
+ if (p.messages != null) handleData (p);
+ if (p.acks != null) for (int ack : p.acks) handleAck (ack);
+ }
+
+ private void handleData (Packet p)
+ {
+ log ("received packet " + p.seq + ", " + p.size + " bytes");
+ if (p.seq < rxSeq || rxDupe.contains (p.seq)) {
+ log ("duplicate packet");
+ sendAck (p.seq); // Original ack may have been lost
+ }
+ else if (p.seq == rxSeq) {
+ log ("packet in order");
+ // Find the sequence number of the next missing packet
+ int was = rxSeq;
+ while (rxDupe.remove (++rxSeq));
+ log ("rxSeq was " + was + ", now " + rxSeq);
+ // Deliver the packet
+ unpack (p);
+ sendAck (p.seq);
+ }
+ else if (p.seq < rxSeq + SEQ_RANGE) {
+ log ("packet out of order - expected " + rxSeq);
+ if (rxDupe.add (p.seq)) unpack (p);
+ else log ("duplicate packet");
+ sendAck (p.seq); // Original ack may have been lost
+ }
+ // This indicates a misbehaving sender - discard the packet
+ else log ("warning: received " + p.seq + " before " + rxSeq);
+ }
+
+ private void handleAck (int ack)
+ {
+ log ("received ack " + ack);
+ double now = Event.time();
+ Iterator<Packet> i = txBuffer.iterator();
+ while (i.hasNext()) {
+ Packet p = i.next();
+ double age = now - p.sent;
+ // Explicit ack
+ if (p.seq == ack) {
+ log ("packet " + p.seq + " acknowledged");
+ i.remove();
+ // Update the congestion window
+ window.bytesAcked (p.size);
+ // Update the average round-trip time
+ rtt = rtt * RTT_DECAY + age * (1.0 - RTT_DECAY);
+ log ("round-trip time " + age);
+ log ("average round-trip time " + rtt);
+ break;
+ }
+ // Fast retransmission
+ if (p.seq < ack && age > FRTO * rtt + MAX_DELAY) {
+ p.sent = now;
+ log ("fast retransmitting packet " + p.seq);
+ node.net.send (p, address, latency);
+ window.fastRetransmission (now);
+ }
+ }
+ // Recalculate the maximum sequence number
+ if (txBuffer.isEmpty()) txMaxSeq = txSeq + SEQ_RANGE - 1;
+ else txMaxSeq = txBuffer.peek().seq + SEQ_RANGE - 1;
+ log ("maximum sequence number " + txMaxSeq);
+ // Send as many packets as possible
+ while (send());
+ }
+
+ // Add messages to a packet
+ private void pack (Packet p, int payload)
+ {
+ Iterator<Deadline<Message>> i = msgQueue.iterator();
+ while (i.hasNext()) {
+ Message m = i.next().item;
+ if (m.size > payload) break;
+ i.remove();
+ msgQueueSize -= m.size;
+ p.addMessage (m);
+ payload -= m.size;
+ }
+ }
+
+ // Remove messages from a packet and deliver them to the node
+ private void unpack (Packet p)
+ {
+ if (p.messages == null) return;
+ for (Message m : p.messages) node.handleMessage (m, this);
+ }
+
+ // Called by Node, returns the next coalescing or retx deadline
+ public double checkTimeouts()
+ {
+ log ("checking timeouts");
+ // Send as many packets as possible
+ while (send());
+
+ double now = Event.time();
+ if (txBuffer.isEmpty()) {
+ log ("no packets in flight");
+ return deadline (now);
+ }
+ for (Packet p : txBuffer) {
+ if (now - p.sent > RTO * rtt + MAX_DELAY) {
+ // Retransmission timeout
+ log ("retransmitting packet " + p.seq);
+ p.sent = now;
+ node.net.send (p, address, latency);
+ window.timeout (now);
+ }
+ }
+ return Math.min (now + MAX_DELAY, deadline (now));
+ }
+
+ // Work out when the first message or ack needs to be sent
+ private double deadline (double now)
+ {
+ return Math.min (ackDeadline(), msgDeadline (now));
+ }
+
+ // Work out when the first ack needs to be sent
+ private double ackDeadline()
+ {
+ Deadline<Integer> firstAck = ackQueue.peek();
+ if (firstAck == null) return Double.POSITIVE_INFINITY;
+ return firstAck.deadline;
+ }
+
+ // Work out when the first message needs to be sent
+ private double msgDeadline (double now)
+ {
+ Deadline<Message> firstMsg = msgQueue.peek();
+ if (firstMsg == null) return Double.POSITIVE_INFINITY;
+ double deadline = firstMsg.deadline;
+ if (msgQueueSize < Packet.SENSIBLE_PAYLOAD) return deadline;
+ if (window.available() < Packet.SENSIBLE_PAYLOAD
+ + Packet.HEADER_SIZE)
+ return Double.POSITIVE_INFINITY; // Wait for an ack
+ if (node.bandwidth.available() < Packet.SENSIBLE_PAYLOAD
+ + Packet.HEADER_SIZE)
+ return Math.max (deadline, now + Node.SHORT_SLEEP);
+ return now;
+ }
+
+ public void log (String message)
+ {
+ Event.log (node.net.address + ":" + address + " " + message);
+ }
+}
Deleted: trunk/apps/load-balancing-sims/phase6/Request.java
===================================================================
--- trunk/apps/load-balancing-sims/phase5-coalescing/Request.java
2006-08-08 14:39:02 UTC (rev 9966)
+++ trunk/apps/load-balancing-sims/phase6/Request.java 2006-08-20 22:58:19 UTC
(rev 10220)
@@ -1,28 +0,0 @@
-class Request extends Message
-{
- private static int nextId = 0;
-
- public final int id; // The unique ID of the request
- public final int key; // The requested key
-
- // Start a new request
- public Request (int key)
- {
- id = nextId++;
- this.key = key;
- size = Message.HEADER_SIZE + Message.ID_SIZE + Message.KEY_SIZE;
- }
-
- // Forward a request
- public Request (int id, int key)
- {
- this.id = id;
- this.key = key;
- size = Message.HEADER_SIZE + Message.ID_SIZE + Message.KEY_SIZE;
- }
-
- public String toString()
- {
- return new String ("request (" + id + "," + key + ")");
- }
-}
Modified: trunk/apps/load-balancing-sims/phase6/RequestState.java
===================================================================
--- trunk/apps/load-balancing-sims/phase5-coalescing/RequestState.java
2006-08-08 14:39:02 UTC (rev 9966)
+++ trunk/apps/load-balancing-sims/phase6/RequestState.java 2006-08-20
22:58:19 UTC (rev 10220)
@@ -2,6 +2,7 @@
import java.util.HashSet;
import java.util.Collection;
+import messages.Request;
class RequestState
{
Deleted: trunk/apps/load-balancing-sims/phase6/Response.java
===================================================================
--- trunk/apps/load-balancing-sims/phase5-coalescing/Response.java
2006-08-08 14:39:02 UTC (rev 9966)
+++ trunk/apps/load-balancing-sims/phase6/Response.java 2006-08-20 22:58:19 UTC
(rev 10220)
@@ -1,18 +0,0 @@
-class Response extends Message
-{
- public final int id; // The unique ID of the request
- public final int key; // The requested key
-
- public Response (int id, int key)
- {
- this.id = id;
- this.key = key;
- size = Message.HEADER_SIZE + Message.ID_SIZE +
- Message.KEY_SIZE + Message.DATA_SIZE;
- }
-
- public String toString()
- {
- return new String ("response (" + id + "," + key + ")");
- }
-}
Deleted: trunk/apps/load-balancing-sims/phase6/RouteNotFound.java
===================================================================
--- trunk/apps/load-balancing-sims/phase5-coalescing/RouteNotFound.java
2006-08-08 14:39:02 UTC (rev 9966)
+++ trunk/apps/load-balancing-sims/phase6/RouteNotFound.java 2006-08-20
22:58:19 UTC (rev 10220)
@@ -1,18 +0,0 @@
-// Note: for the purposes of this simulation, RejectedLoop and RouteNotFound
-// are equivalent
-
-class RouteNotFound extends Message
-{
- public final int id; // The unique ID of the request
-
- public RouteNotFound (int id)
- {
- this.id = id;
- size = Message.HEADER_SIZE + Message.ID_SIZE;
- }
-
- public String toString()
- {
- return new String ("route not found (" + id + ")");
- }
-}
Deleted: trunk/apps/load-balancing-sims/phase6/Sim.java
===================================================================
--- trunk/apps/load-balancing-sims/phase5-coalescing/Sim.java 2006-08-08
14:39:02 UTC (rev 9966)
+++ trunk/apps/load-balancing-sims/phase6/Sim.java 2006-08-20 22:58:19 UTC
(rev 10220)
@@ -1,31 +0,0 @@
-// Interesting parameters to play with: txSpeed and rxSpeed, retransmission
-// timeout, window sizes, AIMD increase and decrease (Peer.java), queue sizes
-// (NetworkInterface.java), packet size (Packet.java).
-
-class Sim
-{
- public static void main (String[] args)
- {
- double txSpeed = 15000, rxSpeed = 15000; // Bytes per second
- // rxSpeed = Math.exp (rand.nextGaussian() + 11.74);
- // txSpeed = rxSpeed / 5.0;
-
- Network.reorder = true;
- Network.lossRate = 0.001;
-
- Node n0 = new Node (txSpeed, rxSpeed);
- Node n1 = new Node (txSpeed, rxSpeed);
- Node n2 = new Node (txSpeed, rxSpeed);
- Node n3 = new Node (txSpeed, rxSpeed);
-
- n0.connectBothWays (n1, 0.1);
- n1.connectBothWays (n2, 0.1);
- n1.connectBothWays (n3, 0.1);
- n2.connectBothWays (n3, 0.1);
-
- Event.schedule (n0, 0.0, Node.GENERATE_REQUEST, null);
-
- // Run the simulation
- Event.run();
- }
-}
Copied: trunk/apps/load-balancing-sims/phase6/Sim.java (from rev 10162,
trunk/apps/load-balancing-sims/phase5-coalescing/Sim.java)
Added: trunk/apps/load-balancing-sims/phase6/messages/Message.java
===================================================================
--- trunk/apps/load-balancing-sims/phase5-coalescing/messages/Message.java
2006-08-08 14:39:02 UTC (rev 9966)
+++ trunk/apps/load-balancing-sims/phase6/messages/Message.java 2006-08-20
22:58:19 UTC (rev 10220)
@@ -0,0 +1,13 @@
+// A high-level message (as opposed to a low-level packet)
+
+package messages;
+
+public class Message
+{
+ public final static int HEADER_SIZE = 30; // Sequence number, MAC, etc
+ public final static int ID_SIZE = 16; // Size of unique request ID
+ public final static int KEY_SIZE = 32; // Size of routing key
+ public final static int DATA_SIZE = 1024; // Size of data block
+
+ public int size; // Size in bytes
+}
Added: trunk/apps/load-balancing-sims/phase6/messages/Request.java
===================================================================
--- trunk/apps/load-balancing-sims/phase5-coalescing/messages/Request.java
2006-08-08 14:39:02 UTC (rev 9966)
+++ trunk/apps/load-balancing-sims/phase6/messages/Request.java 2006-08-20
22:58:19 UTC (rev 10220)
@@ -0,0 +1,30 @@
+package messages;
+
+public class Request extends Message
+{
+ private static int nextId = 0;
+
+ public final int id; // The unique ID of the request
+ public final int key; // The requested key
+
+ // Start a new request
+ public Request (int key)
+ {
+ id = nextId++;
+ this.key = key;
+ size = Message.HEADER_SIZE + Message.ID_SIZE + Message.KEY_SIZE;
+ }
+
+ // Forward a request
+ public Request (int id, int key)
+ {
+ this.id = id;
+ this.key = key;
+ size = Message.HEADER_SIZE + Message.ID_SIZE + Message.KEY_SIZE;
+ }
+
+ public String toString()
+ {
+ return new String ("request (" + id + "," + key + ")");
+ }
+}
Added: trunk/apps/load-balancing-sims/phase6/messages/Response.java
===================================================================
--- trunk/apps/load-balancing-sims/phase5-coalescing/messages/Response.java
2006-08-08 14:39:02 UTC (rev 9966)
+++ trunk/apps/load-balancing-sims/phase6/messages/Response.java
2006-08-20 22:58:19 UTC (rev 10220)
@@ -0,0 +1,20 @@
+package messages;
+
+public class Response extends Message
+{
+ public final int id; // The unique ID of the request
+ public final int key; // The requested key
+
+ public Response (int id, int key)
+ {
+ this.id = id;
+ this.key = key;
+ size = Message.HEADER_SIZE + Message.ID_SIZE +
+ Message.KEY_SIZE + Message.DATA_SIZE;
+ }
+
+ public String toString()
+ {
+ return new String ("response (" + id + "," + key + ")");
+ }
+}
Added: trunk/apps/load-balancing-sims/phase6/messages/RouteNotFound.java
===================================================================
---
trunk/apps/load-balancing-sims/phase5-coalescing/messages/RouteNotFound.java
2006-08-08 14:39:02 UTC (rev 9966)
+++ trunk/apps/load-balancing-sims/phase6/messages/RouteNotFound.java
2006-08-20 22:58:19 UTC (rev 10220)
@@ -0,0 +1,20 @@
+// Note: for the purposes of this simulation, RejectedLoop and RouteNotFound
+// are equivalent
+
+package messages;
+
+public class RouteNotFound extends Message
+{
+ public final int id; // The unique ID of the request
+
+ public RouteNotFound (int id)
+ {
+ this.id = id;
+ size = Message.HEADER_SIZE + Message.ID_SIZE;
+ }
+
+ public String toString()
+ {
+ return new String ("route not found (" + id + ")");
+ }
+}