⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 .#meednode.java.1.41

📁 DTNSim2 is a simulator for Delay-Tolerant Networks (DTNs) written in Java. It is based on Sushant Ja
💻 41
📖 第 1 页 / 共 5 页
字号:
			return false;		}		/** Process incoming topology messages. */		public boolean acceptMessage(ProtocolStackMessage msg, Contact contact, int size)		{			if (size < msg.getLength() || msg.getProtocolID() != PROTO_MEED_ID)				return false;			if (msg.isRoutingMessage())			{				return receivedProtocolMessage(msg, contact);			}			return false;		}		/**		 * Record contact statistics when the link comes up.		 */		public void contactUp(Contact ct)		{			// It might be only contact directed FROM this node!			if (ct.getSource() != parent)				return;			assert !connectedContacts.contains(ct);			metric.contactUp(ct, network.getCurrentTime());			// See if our link state has changed and needs to be updated			HashMap<Contact, Double> linkState = metric.contactWeights(network.getCurrentTime());			if (contactStateChanged(linkState))			{				topologyChanged(); // invalidate routing cache				// Put the routing update into an object				selfSequence += 1;				RoutingUpdate r = new RoutingUpdate();				r.node = this.parent;				r.sequenceNumber = selfSequence;				r.contactWeights = linkState;				boolean updated = topology.processUpdate(r);				if (network.vShouldLog(Verbose.DEBUG1))					network.vprint("MEED ProcessedUpdate (self) for linkState: " + linkState + ": " + updated);				if (!updated)					return;				// Flood this local topology update to all other nodes				for (Iterator<Contact> i = connectedContacts.iterator(); i.hasNext();)				{					Contact c = i.next();					assert c != ct;					// Package this up in an update message					// base size is 16 bytes (number of updates, node id,					// sequence number, length, then 8 bytes per link (node id,					// contact weight))					int size = 16 + 8 * linkState.size();					ArrayList<RoutingUpdate> temp = new ArrayList<RoutingUpdate>();					temp.add(r);					ProtocolStackMessage updateMsg = new ProtocolStackMessage(network.getNextRoutingMessageId(),							network.getCurrentTime(), parent, c.getDest(), 0, size, true);					updateMsg.setProtocolID(PROTO_MEED_ID);					updateMsg.storeData(routingUpdateKey, temp);					getMsgsToSend(c).add(updateMsg);				}			}		}		/**		 * Exchange link state information when the link first becomes		 * available.		 */		public boolean contactIdle(Contact ct)		{			if (super.contactIdle(ct))			{				return true;			}			if (!connectedContacts.contains(ct))			{				connectedContacts.add(ct);				// Invalidate the routing state now that the link is available				topologyChanged();				if (network.vShouldLog(Verbose.DEBUG1))					network.vprint("MEED " + this.parent + " - routing state invalidated.");				// This is a newly connected node: send the routing table				// summary				HashMap routingSummary = topology.getRoutingSummary();				// 4 bytes per node id, 4 bytes per weight, 4 bytes for the				// length				int size = routingSummary.size() * 8 + 4;				ProtocolStackMessage msg = new ProtocolStackMessage(network.getNextRoutingMessageId(), network						.getCurrentTime(), parent, ct.getDest(), 0, size, true);				msg.setProtocolID(PROTO_MEED_ID);				msg.storeData(routingSummaryKey, routingSummary);				ct.sendMessage(msg);				return true;			}			if (network.vShouldLog(Verbose.DEBUG1))				network.vprint("MEED " + this.parent + " TopologyIdleContact for " + ct + " returns "						+ (!isGettingUpdates()) + "; GettingUpdates: " + gettingUpdates);			// We force the queue to go idle if we *are* getting updates			return isGettingUpdates();		}		public void contactDown(Contact ct)		{			super.contactDown(ct);			connectedContacts.remove(ct);			gettingUpdates.remove(ct);						// Metrics only care about contacts that go FROM this node			if (ct.getSource() == this.parent)			{				metric.contactDown(ct, network.getCurrentTime());			}			// Contacts going up and down mean that the routing state changes:			// invalidate the cached routing			topologyChanged();		}		/**		 * The topology of the current DTN.		 */		protected class DTNTopology implements Dijkstra.Graph<Node, Contact, ProtocolStackMessage>		{			TreeSet<Node> forbiddenNodes = null;			public void setForbiddenNodes(TreeSet<Node> nodes)			{				forbiddenNodes = nodes;			}			public void clearForbiddenNodes()			{				forbiddenNodes = null;			}			public DTNTopology()			{			}			/** Maps contacts to their most recent weights. */			protected HashMap<Contact, Double> contactWeights = new HashMap<Contact, Double>();			/** Maps nodes to their most recent sequence numbers. */			protected HashMap<Node, Integer> nodeSequenceNumbers = new HashMap<Node, Integer>();			/** Maps nodes to their contacts. */			protected HashMap<Node, ArrayList<Contact>> nodeContacts = new HashMap<Node, ArrayList<Contact>>();			/**			 * Returns the weight for the specified link object. The time and			 * obj are used so the graph can define weights that depend on the			 * context.			 */			public double getWeight(Contact ofContact, double time, ProtocolStackMessage contextMsg)			// public double linkWeight(Graph.Link link, double time, Object			// obj)			{				double weight = 0;				// If the specified contact is currently up, then the weight for				// local routing is zero				if (connectedContacts.contains(ofContact))					weight = 0;				else					weight = contactWeights.get(ofContact).doubleValue();				// ~ System.out.println( Simulator.time() + " Contact " + link +				// " weight " + weight );				return weight;			}			/**			 * Returns an Iterator over all the Contacts that leave 'fromNode'			 * Node.			 */			public Iterator<? extends Contact> getArcsOut(Node fromNode)			{				ArrayList<Contact> contacts = nodeContacts.get(fromNode);				if (contacts == null)				{					return (new ArrayList<Contact>()).iterator();				}				if (forbiddenNodes == null)				{					return contacts.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();			}			/** Returns the source node for arc. */			public Node getSource(Contact arc)			{				return arc.getSource();			}			/** Returns the destination node for arc. */			public Node getDest(Contact arc)			{				return arc.getDest();			}			public int compareNodes(Node a, Node b)			{				return a.compareTo(b);			}			public HashMap<? extends Node, ? extends Integer> getRoutingSummary()			{				return new HashMap<Node, Integer>(nodeSequenceNumbers);			}			public boolean processUpdate(RoutingUpdate update)			{				return this.processUpdate(update.node, update.sequenceNumber, update.contactWeights);			}			public boolean processUpdate(Node node, int sequenceNumber, HashMap<Contact, Double> updatedContactWeights)			{				// Verify that this update is more recent than the previous one				if (nodeSequenceNumbers.get(node) != null && nodeSequenceNumbers.get(node).intValue() >= sequenceNumber)				{					// This update is the same or older than our current state:					// ignore it					return false;				}				// Update the sequence number				nodeSequenceNumbers.put(node, new Integer(sequenceNumber));				// Remove current contacts, in case the new update has *fewer*				// contacts than the				// previous update (a contact has expired due to being down for				// too long)				ArrayList<Contact> oldContacts = nodeContacts.get(node);				nodeContacts.put(node, new ArrayList<Contact>());				if (oldContacts != null)				{					for (Iterator<Contact> i = oldContacts.iterator(); i.hasNext();)					{						Contact c = i.next();						assert c.getSource() == node;						assert contactWeights.containsKey(c);						contactWeights.remove(c);					}				}				// Add all the new contacts				contactWeights.putAll(updatedContactWeights);				ArrayList<Contact> cToAdd = new ArrayList<Contact>(updatedContactWeights.keySet());				nodeContacts.put(node, cToAdd);				// Add "invalid" sequence numbers for any nodes which we have				// just discovered				// This assures that routing will still work, even though we				// don't have a sequence number				// for those nodes yet				Integer invalidSequence = new Integer(-1);				for (Iterator<Contact> i = updatedContactWeights.keySet().iterator(); i.hasNext();)				{					Contact c = i.next();					assert c.getSource() == node;					if (!nodeSequenceNumbers.containsKey(c.getDest()))					{						nodeSequenceNumbers.put(c.getDest(), invalidSequence);					}					if (network.vShouldLog(Verbose.DEBUG1))						network.vprint("MEED Update contact: Weight of " + c + " = " + updatedContactWeights.get(c));					// ~ if ( id() == 0 ) System.out.println( Simulator.time() +					// " update contact: " + c.src() + " -> " + c.dst() + " = "					// + updatedContactWeights.get( c ) );				}				// We actually did process an update				return true;			}			/**			 * Create an array of routing updates that are more accurate than			 * the ones represented by the routingSummary.			 */			public ArrayList<RoutingUpdate> getRoutingUpdates(HashMap<? extends Node, ? extends Integer> routingSummary)			{				ArrayList<RoutingUpdate> updates = new ArrayList<RoutingUpdate>();				for (Iterator<Map.Entry<Node, Integer>> i = nodeSequenceNumbers.entrySet().iterator(); i.hasNext();)				{					Map.Entry<Node, Integer> entry = i.next();					Node node = entry.getKey();					Integer ourSequence = entry.getValue();					// A -1 indicates that our topology is currently not					// complete, and we actually					// have no information about that node, but we know it					// exists because we have					// a contact to it					if (ourSequence.intValue() == -1)						continue;					Integer otherSequence = routingSummary.get(node);					if (otherSequence == null || otherSequence.intValue() < ourSequence.intValue())					{						// TIf they are missing the information, or if their						// information is out of date,						// send them the information about this node						RoutingUpdate update = new RoutingUpdate();						update.node = node;						update.sequenceNumber = ourSequence.intValue();						// Copy the contact weights from our topology state						update.contactWeights = new HashMap<Contact, Double>();						for (Iterator j = nodeContacts.get(node).iterator(); j.hasNext();)						{							Contact c = (Contact) j.next();							update.contactWeights.put(c, contactWeights.get(c));						}						updates.add(update);					}				}				return updates;			}			/** Tests if we need any of the updates in the routing summary. */			// TODO: Can this be combined with the previous test somehow?			public boolean needRoutingUpdates(HashMap<? extends Node, ? extends Integer> routingSummary)			{				for (Iterator i = routingSummary.entrySet().iterator(); i.hasNext();)				{					Map.Entry entry = (Map.Entry) i.next();					Node node = (Node) entry.getKey();					Integer otherSequence = (Integer) entry.getValue();					Integer ourSequence = nodeSequenceNumbers.get(node);					if (ourSequence == null || ourSequence.intValue() < otherSequence.intValue())					{						// They have a more recent update that we need						return true;					}				}				return false;			}		}		protected class TreeNode		{			public MEEDDijkstra routing = null;			public HashMap<Node, TreeNode> down = null;		}	}	/** Routes messages based on the topology provided. */	public static class TopologyRoutingEventHandler extends EventHandler implements MEEDTopologyObserver	{		private static int myID = getHandlerID();		protected MEEDNode parent = null;		protected Collection<ProtocolStackMessage> buffer = null;		protected MEEDTopologyEventHandler topology = null;		protected FinalDestinationEventHandler finalAgent;		public TopologyRoutingEventHandler(MEEDNode node, MEEDTopologyEventHandler topology,				FinalDestinationEventHandler finalA, Collection<ProtocolStackMessage> buffer)		{			super(myID);			this.parent = node;			this.buffer = buffer;			this.topology = topology;			this.finalAgent = finalA;			topology.addObserver(this);		}		public TopologyRoutingEventHandler(int setID, MEEDNode node, MEEDTopologyEventHandler topology,				FinalDestinationEventHandler finalA, Collection<ProtocolStackMessage> buffer)		{			super(setID);			this.parent = node;			this.buffer = buffer;			this.topology = topology;			this.finalAgent = finalA;			topology.addObserver(this);		}		/**		 * Records the contacts that have already received all messages we could		 * have sent to them. This set contains contacts directed FROM this Node		 * (this node is their source)		 */		HashSet<Contact> finishedWithDestinations = new HashSet<Contact>();		public boolean contactIdle(Contact ct)		{			if (this.parent.getNetwork().vShouldLog(Verbose.DEBUG1))				this.parent.getNetwork().vprint("MEED " + this.parent + " MEEDRouting idleContact: " + ct);			// The MEED topology agent should prevent us from getting			// idleContact if it is busy getting updates			assert !topology.isGettingUpdates();			// If we are not busy getting updates from anyone, and we have not			// yet finished with this destination,			// place an iterator			if (!finishedWithDestinations.contains(ct))			{				Iterator<ProtocolStackMessage> i = buffer.iterator();				while (i.hasNext())				{					ProtocolStackMessage m = i.next();					Node dest = m.getDestNode();					MEEDDijkstra routing = (MEEDDijkstra) m.getData(MSG_ROUTING);					if (routing == null)					{						routing = topology.routingCache(m);						if (parent.routingPolicy != ROUTING_POLICY_TOPOLOGY)						{							m.storeData(MSG_ROUTING, routing);						}					}					ArrayList<Contact> route = routing.routeTo(dest);					// System.out.println("Route: " + route);					// If this route uses our contact as the next hop,					// ~ System.out.println( "route size " + route.size() );					// ~ if ( route.size() > 0 ) System.out.println( "next					// hop = " + route.get(0) + " cost = " +					// routingCache().getCost( m.dstNode() ) );					if (route != null && route.size() > 0 && route.get(0) == ct && parent.allowSend(m, ct))					{						i.remove();						// Store predicted delivery time (not to be used by						// other nodes, but maybe by other protocols/layers						// of this node. And statistics.						Double cost = routing.getCost(dest);						if (m.getSourceNode() == parent && m.getData(MSG_LEFT_SOURCE) == null)						{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -