📄 .#replicationmeednode.java.1.16
字号:
package implementations;import java.util.ArrayList;import java.util.Collection;import java.util.HashMap;import java.util.TreeSet;import java.util.Iterator;import java.util.ListIterator;import simulator.Contact;import simulator.Dijkstra;import simulator.Node;import simulator.Message;import util.CommandStatus;import util.Verbose;public class ReplicationMEEDNode extends MEEDNode{ protected static int PROTO_RMEED_ID = ProtocolStackMessage.getNewProtocolID(); protected static Message.Header messageExpiryTime = new Message.Header(); protected ArrayList<ProtocolStackMessage> replicationBuffer = null; protected HashMap<Integer, ProtocolStackMessage> mIDs = null; protected TopologyRoutingEventHandler routingRepAgent = null; protected FinalDestinationEventHandler finalRepDestinationAgent = null; protected double delivToExpiry = 10; protected boolean oneReplica = true; // This constructor is used only to create default_node instance, // so there is no need to add handlers. public ReplicationMEEDNode() { super(); } public ReplicationMEEDNode(ReplicationMEEDNode org) { super(org); } public void initNode() { replicationBuffer = new ArrayList<ProtocolStackMessage>(); mIDs = new HashMap<Integer, ProtocolStackMessage>(); finalDestinationAgent = new FinalDestinationEventHandler(this, primaryQueue); finalRepDestinationAgent = new RepFinalDestinationEventHandler(this, replicationBuffer); topologyAgent = new RMEEDTopologyEventHandler(this); routingAgent = new TopologyRoutingEventHandler(this, topologyAgent, finalDestinationAgent, primaryQueue); routingRepAgent = new TopologyRepRoutingEventHandler(this, topologyAgent, finalRepDestinationAgent, replicationBuffer); // Add the event handlers in the proper order appendEventHandler(finalDestinationAgent); appendEventHandler(finalRepDestinationAgent); appendEventHandler(topologyAgent); appendEventHandler(routingAgent); appendBufferHandler(routingRepAgent); if (useACK) { ACKAgent = new ACKHandler(this); appendEventHandler(ACKAgent); appendBufferHandler(ACKAgent); } appendEventHandler(routingRepAgent); } private void storeInRepBuffer(ProtocolStackMessage msg) { assert replicationBuffer != null; if (replicationBuffer.size() < 1) { replicationBuffer.add(msg); mIDs.put(msg.getId(), msg); return; } ListIterator<ProtocolStackMessage> it = replicationBuffer.listIterator(); double f = msg.getCreationTime(); while (it.hasNext()) { ProtocolStackMessage m = it.next(); if (m.getCreationTime() < f) { it.previous(); it.add(msg); mIDs.put(msg.getId(), msg); return; } } mIDs.put(msg.getId(), msg); replicationBuffer.add(msg); } protected boolean allowSend(ProtocolStackMessage msg, Contact ct) { Double exp = (Double) msg.getData(messageExpiryTime); if (exp != null && exp.doubleValue() < network.getCurrentTime()) { return false; } TreeSet<Node> set = msg.forbiddenNodes(); if (set == null || !set.contains(ct.getDest())) { return true; } return false; } protected double expiryTime(double predictDelivery) { return predictDelivery * delivToExpiry + network.getCurrentTime(); } 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; try { if (param.equals("deliv_expiry_factor")) { double f = Double.parseDouble(part.get(1)); if (f < 0) { return new CommandStatus("Deliv to expiry factor can not be < 0!"); } delivToExpiry = f; return ok; } else if (param.equals("one_replica")) { oneReplica = Boolean.parseBoolean(part.get(1)); return ok; } } catch (NumberFormatException e) { return new CommandStatus("Error parsing value of parameter '" + param + "': " + e); } return null; } public static class RepFinalDestinationEventHandler extends FinalDestinationEventHandler { double lastCheck = -1; ReplicationMEEDNode repParent = null; public RepFinalDestinationEventHandler(ReplicationMEEDNode node, Collection<ProtocolStackMessage> buffer) { super(node, buffer); repParent = node; } public boolean contactIdle(Contact ct) { if (lastCheck < parent.getNetwork().getCurrentTime()) { lastCheck = parent.getNetwork().getCurrentTime(); Iterator<ProtocolStackMessage> it = buffer.iterator(); while (it.hasNext()) { ProtocolStackMessage m = it.next(); Double exp = (Double) m.getData(messageExpiryTime); if (exp.doubleValue() < lastCheck) { parent.freeCapacity(m); it.remove(); repParent.mIDs.remove(m.getId()); } } } return super.contactIdle(ct); } } /** Distributes ReplicationMEED topology updates. */ public static class RMEEDTopologyEventHandler extends MEEDTopologyEventHandler { RDTNTopology rTopology = null; TreeNode treeCache = null; int lastSetHash = 0; int lastSetSize = 0; Dijkstra<Node, Contact, ProtocolStackMessage> lastR = null; public RMEEDTopologyEventHandler(MEEDNode node) { super(node); rTopology = new RDTNTopology(); this.topology = rTopology; } protected void topologyChanged(int i) { if (i > 0) { treeCache = null; lastSetHash = 0; lastSetSize = 0; lastR = null; } super.topologyChanged(i); } protected Dijkstra<Node, Contact, ProtocolStackMessage> rGetCache(TreeSet<Node> set) { if (lastSetHash == set.hashCode() && set.size() == lastSetSize && lastR != null) return lastR; if (false) { rTopology.setForbiddenNodes(set); Dijkstra<Node, Contact, ProtocolStackMessage> r = new Dijkstra<Node, Contact, ProtocolStackMessage>( rTopology, parent, network.getCurrentTime(), null); rTopology.clearForbiddenNodes(); lastSetHash = set.hashCode(); lastSetSize = set.size(); lastR = r; return r; } if (treeCache == null) { treeCache = new TreeNode(); } Iterator<? extends Node> it = set.iterator(); if (!it.hasNext()) { assert false; } TreeNode lastLevel = treeCache; while (it.hasNext()) { Node n = it.next(); if (lastLevel.down == null) { TreeNode tn = new TreeNode(); lastLevel.down = new HashMap<Node, TreeNode>(1); lastLevel.down.put(n, tn); lastLevel = tn; } else { TreeNode tn = lastLevel.down.get(n); if (tn == null) { tn = new TreeNode(); lastLevel.down.put(n, tn); } lastLevel = tn; } } if (lastLevel.routing == null) { rTopology.setForbiddenNodes(set); lastLevel.routing = new Dijkstra<Node, Contact, ProtocolStackMessage>(rTopology, parent, network .getCurrentTime(), null); rTopology.clearForbiddenNodes(); } lastSetHash = set.hashCode(); lastSetSize = set.size(); lastR = lastLevel.routing; return lastLevel.routing; } public Dijkstra<Node, Contact, ProtocolStackMessage> routingCache(ProtocolStackMessage forMsg) { if (forMsg == null) { return super.routingCache(forMsg); } TreeSet<Node> set = forMsg.forbiddenNodes(); if (set == null || set.size() < 1) { return super.routingCache(forMsg); } Dijkstra<Node, Contact, ProtocolStackMessage> routing = super.routingCache(forMsg); if (routing == null) return null; ArrayList<Contact> route = routing.routeTo(forMsg.getDestNode()); if (route == null) return routing; Iterator<Node> it = set.iterator(); while (it.hasNext()) { if (route.contains(it.next())) { return rGetCache(set); } } return routing; } protected class RDTNTopology extends DTNTopology { TreeSet<Node> forbiddenNodes = null; public void setForbiddenNodes(TreeSet<Node> nodes) { forbiddenNodes = nodes; } public void clearForbiddenNodes() { forbiddenNodes = null; } /** * Returns an Iterator over all the Contacts that leave 'fromNode' * Node. */ public Iterator<? extends Contact> getArcsOut(Node fromNode) { if (forbiddenNodes == null) { return super.getArcsOut(fromNode); } ArrayList<Contact> contacts = nodeContacts.get(fromNode); if (contacts == null) { return (new ArrayList<Contact>()).iterator(); } int s = contacts.size(); Iterator<Contact> it = contacts.iterator(); if (s < 1) { return it; } ArrayList<Contact> ret = new ArrayList<Contact>(s); while (it.hasNext()) { Contact c = it.next(); if (!forbiddenNodes.contains(c.getDest())) { ret.add(c); } } return ret.iterator(); } } protected class TreeNode {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -