1. 程式人生 > >ONE筆記:DirectDlivery路由演算法(ONE模擬執行機制解析)

ONE筆記:DirectDlivery路由演算法(ONE模擬執行機制解析)

DirectDlivery路由要點

DirectDlivery(DD)演算法是基礎路由演算法,是基於flooding的一種極端情況,每個節點只將訊息直接傳遞給目的節點。通過該演算法模擬,旨在梳理ONE模擬執行機制。 特點:開銷低,效率低,節點跳數為1 工作機制:不考慮中繼節點的選擇——不向任何中繼節點複製訊息,源節點一直保持快取訊息,直到進入目的節點的通訊範圍。

DirectDlivery程式碼解析

基於平臺:ONE + Eclipse on MacOS

1. 首先看DirectDeliveryRouter中的update程式碼

 update() 可以理解成我們習慣的main() 函式,即程式碼的入口
public void update() {
		super.update();
		if (isTransferring() || !canStartTransfer()) {
			return; // can't start a new transfer
		}
		// Try only the messages that can be delivered to final recipient
		if (exchangeDeliverableMessages() != null) {
			return; // started a transfer
		}
	}

這裡的update()是被重寫了,具體看ONE的類繼承 ONE中演算法類的繼承關係:

(我們自己寫演算法類的時候也需要這樣繼承)

// DirectDeliveryRouter.java
public abstract class ActiveRouter extends MessageRouter{}
public class DirectDeliveryRouter extends ActiveRouter{}

可見AnyRouter – extends–> ActiveRouter – extends–>MessageRouter

MessageRouter是最終的父類(抽象類)

2. 看父類MessageRouter中的update程式碼

首先看父類的update

//MessageRouter.java
public void update(){
		for (Collection<Application> apps : this.applications.values()) {
			for (Application app : apps) {
				app.update(this.host);
			}
		}
	}

程式碼解析:

Application集合型別是ONE自定義的有關於事件監聽的類,它有兩個屬性和一些函式(這裡只標出用上的):

//Application.java
private List<ApplicationListener> aListeners = null;
public String	appID	= null;

public abstract void update(DTNHost host);

其中ApplicationListener為獲取事件的介面

//ApplicationListener.java
public interface ApplicationListener {
	/** 
	 * Application has generated an event.
	 * 
	 * @param event		Event name.
	 * @param params	Additional parameters for the event
	 * @param app		Application instance that generated the event.
	 * @param host		The host this application instance is running on.
	 */
	public void gotEvent(String event, Object params, Application app,
			DTNHost host);
}
所以總的看來DirectDeliveryRouter中的update程式碼就是類似於處理事件並更新主機的過程。
由此我們可以看出ONE模擬時由事件驅動的。

3. 接著看ActiveRouter中的update程式碼

//ActiveRouter.java
public void update() {		
		super.update(); //呼叫MessageRouter的update()
		/* in theory we can have multiple sending connections even though
		  currently all routers allow only one concurrent sending connection */
		for (int i=0; i<this.sendingConnections.size(); ) {
			boolean removeCurrent = false;
			Connection con = sendingConnections.get(i);
			/*1. finalize ready transfers ,傳輸完成*/
			if (con.isMessageTransferred()) {
				if (con.getMessage() != null) {
					transferDone(con);//空語句,子類可以覆寫
					con.finalizeTransfer();//訊息傳輸完成,handle訊息***
				} /* else: some other entity aborted transfer */
				removeCurrent = true;
			}
			/*2. remove connections that have gone down */
			else if (!con.isUp()) {//如果連線斷開
				if (con.getMessage() != null) {//但是傳輸資訊又不為空
					transferAborted(con);//空語句,子類可以覆寫
					con.abortTransfer();//刪除訊息***
				}
				removeCurrent = true;
			} 
			if (removeCurrent) {
				/* 3.if the message being sent was holding excess buffer, free it*/
				if (this.getFreeBufferSize() < 0) {//如果剩餘的快取大小不足
					this.makeRoomForMessage(0);
				}
				sendingConnections.remove(i);
			}
			else {
				/* index increase needed only if nothing was removed */
				i++;
			}
		}
		
		/* 4.time to do a TTL check and drop old messages? Only if not sending */
		if (SimClock.getTime() - lastTtlCheck >= TTL_CHECK_INTERVAL && 
				sendingConnections.size() == 0) {//當前時間-上次檢查時間>=檢查時間間隔&&沒有傳送連線
			dropExpiredMessages();//生存週期到期的刪除資訊
			lastTtlCheck = SimClock.getTime();//將上次檢測TTL時間更改為當前時間
		}
		if (energy != null) {//如果還有能量
			/* 5.TODO: add support for other interfaces */
			NetworkInterface iface = getHost().getInterface(1);
			energy.update(iface, getHost().getComBus());;//更新能量模板
		}
	}

由程式碼可見註釋可以很清楚的瞭解ActiveRouter的update()的工作內容。 還遺留幾個問題,mark,稍後探索:

  1. con.finalizeTransfer()是如何處理訊息的?
  2. con.abortTransfer()是如何刪除訊息的?
  3. NetworkInterface iface = getHost().getInterface(1) 是什麼意思?
  4. energy.update(iface, getHost().getComBus())能量模板是什麼東西?