📄 meednode.java
字号:
package implementations;import java.util.ArrayList;import java.util.HashMap;import java.util.Map;import java.util.HashSet;import java.util.Iterator;import java.util.Collection;import java.util.Random;import java.util.TreeSet;import simulator.BasicEvent;import simulator.Event;import simulator.EventSender;import simulator.Network;import simulator.Node;import simulator.Message;import simulator.Contact;import simulator.Dijkstra;import simulator.Stats;import simulator.Stats.StatEntry;import simulator.Stats.StatMsgEntry;import util.CommandStatus;import util.Verbose;public class MEEDNode extends ProtocolStackNode{ protected static int PROTO_MEED_ID = ProtocolStackMessage.getNewProtocolID(); protected static Message.Header MSG_RESEND_TIME = new Message.Header(); protected static Message.Header MSG_RESEND_CNT = new Message.Header(); protected static Message.Header MSG_ROUTING = new Message.Header(); protected static Message.Header MSG_PRED_DELAY = new Message.Header(); protected static Message.Header MSG_LEFT_SOURCE = new Message.Header(); protected static Message.Header MSG_IS_RETRANS = new Message.Header(); protected static Message.Header MSG_LAST_NODE = new Message.Header(); protected final static int ROUTING_POLICY_CREATE = 1; protected final static int ROUTING_POLICY_ACCEPT = 2; protected final static int ROUTING_POLICY_TOPOLOGY = 3; protected final static int METRIC_MEED = 1; protected final static int METRIC_LAST_UP = 2; protected final static int METRIC_WINDOW = 3; protected final static int METRIC_EWMA = 4; // If a link metric changes by more than thirty minutes: propagate an update private static double absoluteThreshold = 30 * 60; // If a link metric changes by more than 5%: propagate an update private static double relativeThreshold = 0.05; protected double msgMinResendTime = 100; protected ArrayList<ProtocolStackMessage> primaryQueue = new ArrayList<ProtocolStackMessage>(); protected FinalDestinationEventHandler finalDestinationAgent = null; protected MEEDTopologyEventHandler topologyAgent = null; protected TopologyRoutingEventHandler routingAgent = null; protected ACKHandler ACKAgent = null; protected boolean useACK = false; protected boolean rndRetrans = false; protected boolean sendACK = true; protected boolean orgsUseBuffer = true; protected boolean noBacktracking = false; protected boolean blocking = false; protected double ackTripModif = 1.0f; protected double ackBackTripModif = 1.0f; protected double ackBothTripModif = 2.0f; // 2 hours min protected double rndMin = 7200; // 48 hours max protected double rndMax = 172800; protected int maxRetrans = 5; protected boolean predDelayPerCopy = true; protected int routingPolicy = ROUTING_POLICY_TOPOLOGY; protected int metricToUse = METRIC_MEED; protected int mySize = 0; protected int lastSizeRefused = -1; protected static int nextSeed = 1; protected Random rnd = new Random(nextSeed++); // This constructor is used only to create default_node instance, // so there is no need to add handlers. public MEEDNode() { super(); } public MEEDNode(MEEDNode org) { super(org); useACK = org.useACK; sendACK = org.sendACK; orgsUseBuffer = org.orgsUseBuffer; noBacktracking = org.noBacktracking; ackTripModif = org.ackTripModif; ackBackTripModif = org.ackBackTripModif; ackBothTripModif = org.ackBothTripModif; predDelayPerCopy = org.predDelayPerCopy; metricToUse = org.metricToUse; routingPolicy = org.routingPolicy; rndRetrans = org.rndRetrans; rndMin = org.rndMin; rndMax = org.rndMax; maxRetrans = org.maxRetrans; blocking = org.blocking; } public void initNode() { finalDestinationAgent = new FinalDestinationEventHandler(this, primaryQueue); topologyAgent = new MEEDTopologyEventHandler(this); routingAgent = new TopologyRoutingEventHandler(this, topologyAgent, finalDestinationAgent, primaryQueue); // Add the event handlers in the proper order appendEventHandler(finalDestinationAgent); appendEventHandler(topologyAgent); appendEventHandler(routingAgent); if (useACK) { ACKAgent = new ACKHandler(this); appendEventHandler(ACKAgent); appendBufferHandler(ACKAgent); } if (blocking) { appendEventHandler(new BufFreeNotify(this)); } } public void defaultLoad() { network.stats().registerFilter("meed_deliv", new MEEDDelivOnlyFilter()); } public void defaultUnload() { network.stats().unregisterFilter("meed_deliv"); } public boolean hasACKForMsg(Message msg) { if (ACKAgent == null) return false; return ACKAgent.hasACKFor(new Integer(msg.getId())); } public CommandStatus parseCommandPart(ArrayList<String> part, String path) { String param = part.get(0); CommandStatus ok = super.parseCommandPart(part, path); if (ok != null) return ok; ok = new CommandStatus(CommandStatus.COMMAND_OK); if (part.size() != 2) return null; int val; double f; try { if (param.equals("absolute_threshold")) { val = Integer.parseInt(part.get(1)); if (val < 1) { return new CommandStatus("Absolute threshold can not be < 1!"); } absoluteThreshold = val; return ok; } else if (param.equals("relative_threshold")) { f = Double.parseDouble(part.get(1)); if (f < 0) { return new CommandStatus("Relative threshold can not be < 0!"); } relativeThreshold = f; return ok; } else if (param.equals("ack_trip_modif")) { f = Double.parseDouble(part.get(1)); if (f < 0) { return new CommandStatus("Ack Trip Modifier can not be < 0!"); } ackTripModif = f; return ok; } else if (param.equals("ack_back_trip_modif")) { f = Double.parseDouble(part.get(1)); if (f < 0) { return new CommandStatus("Ack Back Trip Modifier can not be < 0!"); } ackBackTripModif = f; return ok; } else if (param.equals("ack_both_trip_modif")) { f = Double.parseDouble(part.get(1)); if (f < 0) { return new CommandStatus("Ack Both Trip Modifier can not be < 0!"); } ackBothTripModif = f; return ok; } else if (param.equals("use_ack")) { useACK = Boolean.parseBoolean(part.get(1)); return ok; } else if (param.equals("blocking")) { blocking = Boolean.parseBoolean(part.get(1)); return ok; } else if (param.equals("send_acks")) { sendACK = Boolean.parseBoolean(part.get(1)); return ok; } else if (param.equals("rnd_retrans")) { rndRetrans = Boolean.parseBoolean(part.get(1)); return ok; } else if (param.equals("rnd_min")) { f = Double.parseDouble(part.get(1)); if (f < 1 || f >= rndMax) { return new CommandStatus("Random Min can not be < 1, and have to be greater than Random Max!"); } rndMin = f; return ok; } else if (param.equals("rnd_max")) { f = Double.parseDouble(part.get(1)); if (f < 1 || f <= rndMin) { return new CommandStatus("Random Max can not be < 1, and have to be greater thant Random Min!"); } rndMax = f; return ok; } if (param.equals("max_retrans")) { val = Integer.parseInt(part.get(1)); this.maxRetrans = val; return ok; } else if (param.equals("copies_use_buffer")) { orgsUseBuffer = Boolean.parseBoolean(part.get(1)); return ok; } else if (param.equals("no_backtracking") || param.equals("backtracking")) { noBacktracking = Boolean.parseBoolean(part.get(1)); if (param.equals("backtracking")) noBacktracking = !noBacktracking; return ok; } else if (param.equals("delay_per_copy") || param.equals("pred_delay_per_copy")) { predDelayPerCopy = Boolean.parseBoolean(part.get(1)); return ok; } else if (param.equals("metric")) { String m = part.get(1).toLowerCase(); if (m.equals("meed")) { metricToUse = METRIC_MEED; } else if (m.equals("lastup")) { metricToUse = METRIC_LAST_UP; } else if (m.equals("ewma")) { metricToUse = METRIC_EWMA; } else if (m.equals("window")) { metricToUse = METRIC_WINDOW; } else { return new CommandStatus("Unknown metric: " + part.get(1)); } return ok; } else if (param.equals("routing") || param.equals("routing_policy")) { String m = part.get(1).toLowerCase(); if (m.equals("topology")) { routingPolicy = ROUTING_POLICY_TOPOLOGY; } else if (m.equals("create")) { routingPolicy = ROUTING_POLICY_CREATE; } else if (m.equals("accept")) { routingPolicy = ROUTING_POLICY_ACCEPT; } else { return new CommandStatus("Unknown routing policy: " + part.get(1)); } return ok; } } catch (NumberFormatException e) { return new CommandStatus("Error parsing value of parameter '" + param + "': " + e); } return null; } protected Contact getContactToNode(Node dest) { Iterator<Contact> it = getContactsToNode(dest); // TODO - MEED can work only with network where two nodes can be // connected with only one contact (or not connected at all). // We return here first contact from the list of available contacts. if (it.hasNext()) return it.next(); return null; } public boolean willAcceptMessageSize(int len) { // There is enough free space in a buffer, or we are not blocking if (availableCapacity() >= len || !blocking) return true; // If we remove everything except our own data - there will be enough // space. if (bufferCapacity() - mySize >= len) return true; // If we haven't refused anything, or the last refused // size was LARGER than the one we are refusing now. if (lastSizeRefused < 0 || lastSizeRefused > len) lastSizeRefused = len; // We can't accept that size. return false; } protected boolean allowSend(ProtocolStackMessage msg, Contact ct) { TreeSet<Node> set = msg.forbiddenNodes(); if (blocking && !((MEEDNode) ct.getDest()).willAcceptMessageSize(msg.getLength())) { return false; } if (set != null && set.contains(ct.getDest())) { return false; } return true; } /** * Maps nodes to their most recent summary vector. This is used to restart * the epidemic protocol when new messages arrive. */ protected static class RoutingUpdate { public Node node; public int sequenceNumber; public HashMap<Contact, Double> contactWeights; public RoutingUpdate() { } } /** * This is a simple handler that delivers any messages destined for the * other end of contacts. */ public static class FinalDestinationEventHandler extends EventHandler { protected static int myID = getHandlerID(); protected MEEDNode parent; protected Collection<ProtocolStackMessage> buffer; protected HashSet<Contact> finishedDestinations = new HashSet<Contact>(); public FinalDestinationEventHandler(MEEDNode node, Collection<ProtocolStackMessage> buffer) { super(myID); this.parent = node; this.buffer = buffer; } public void contactUp(Contact ct) { assert !finishedDestinations.contains(ct); } public void contactDown(Contact ct) { finishedDestinations.remove(ct); } public void notifyNewMessage(ProtocolStackMessage m) { Contact c = parent.getContactToNode(m.getDestNode()); // Find out if the destination is one of the contacts that we are // active with if (c != null && finishedDestinations.remove(c)) { // We did remove something: go signal the contact parent.signalContactIdle(c);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -