Router Module analysis of ONE simulator

    If you want to compose your own routing module, you have to derive a new class from the ActiveRouter class and rewrite the update() method and probably the replicate() method too. In this article, we look into these two methods.

    Let's take the DirectDeliveryRouter for an example. The following snippet is the function body of its DirectDeliveryRouter::update() method.

 1      @Override
 2       public   void  update() {
 3           super .update();
 4           if  (isTransferring()  ||   ! canStartTransfer()) {
 5               return //  can't start a new transfer
 6          }
 7          
 8           //  Try only the messages that can be delivered to final recipient
 9           if  (exchangeDeliverableMessages()  !=   null ) {
10               return //  started a transfer
11          }
12      }

    It firstly call the update method of is parent (ActiveRouter). Then if the router is transferring right now it just returns. Here is the ActiveRouter::isTransferring method:

 1  /**
 2       * Returns true if this router is transferring something at the moment or
 3       * some transfer has not been finalized.
 4       *  @return  true if this router is transferring something
 5        */
 6       public   boolean  isTransferring() {
 7           if  ( this .sendingConnections.size()  >   0 ) {
 8               return   true //  sending something
 9          }
10          
11           if  ( this .getHost().getConnections().size()  ==   0 ) {
12               return   false //  not connected
13          }
14          
15          List < Connection >  connections  =  getConnections();
16           for  ( int  i = 0 , n = connections.size(); i < n; i ++ ) {
17              Connection con  =  connections.get(i);
18               if  ( ! con.isReadyForTransfer()) {
19                   return   true ;     //  a connection isn't ready for new transfer(it's busy)
20              }
21          }
22          
23           return   false;        

24     } 

The function Connection::isReadyForTransfer:

1  /**
2       * Returns true if the connection is ready to transfer a message (connection
3       * is up and there is no message being transferred).
4       *  @return  true if the connection is ready to transfer a message
5        */
6       public   boolean  isReadyForTransfer() {
7           return   this .isUp  &&   this .msgOnFly  ==   null

8     } 

The function body of ActiveRouter::canStartTransfer is:

 1  /**
 2       * Makes rudimentary checks (that we have at least one message and one
 3       * connection) about can this router start transfer.
 4       *  @return  True if router can start transfer, false if not
 5        */
 6       protected   boolean  canStartTransfer() {
 7           if  ( this .getNrofMessages()  ==   0 ) {
 8               return   false ;
 9          }
10           if  ( this .getConnections().size()  ==   0 ) {
11               return   false ;
12          }
13          
14           return   true;

15     } 

 

The function body of DirectDeliveryRouter::exchangeDeliverableMessages:

 1  /**
 2       * Exchanges deliverable (to final recipient) messages between this host
 3       * and all hosts this host is currently connected to. First all messages
 4       * from this host are checked and then all other hosts are asked for
 5       * messages to this host. If a transfer is started, the search ends.
 6       *  @return  A connection that started a transfer or null if no transfer
 7       * was started
 8        */
 9       protected  Connection exchangeDeliverableMessages() {
10          List < Connection >  connections  =  getConnections();
11 
12           if  (connections.size()  ==   0 ) {
13               return   null ;
14          }
15          
16          @SuppressWarnings(value  =   " unchecked " )
17          Tuple < Message, Connection >  t  =
18              tryMessagesForConnected(sortByQueueMode(getMessagesForConnected()));
19 
20           if  (t  !=   null ) {
21               return  t.getValue();  //  started transfer
22          }
23          
24           //  didn't start transfer to any node -> ask messages from connected
25           for  (Connection con : connections) {
26               if  (con.getOtherNode(getHost()).requestDeliverableMessages(con)) {
27                   return  con;
28              }
29          }
30          
31           return   null;

32     }

The function body of ActiveRouter::tryMessagesForConnected:

 1       /**
 2       * Tries to send messages for the connections that are mentioned
 3       * in the Tuples in the order they are in the list until one of
 4       * the connections starts transferring or all tuples have been tried.
 5       *  @param  tuples The tuples to try
 6       *  @return  The tuple whose connection accepted the message or null if
 7       * none of the connections accepted the message that was meant for them.
 8        */
 9       protected  Tuple < Message, Connection >  tryMessagesForConnected(
10              List < Tuple < Message, Connection >>  tuples) {
11           if  (tuples.size()  ==   0 ) {
12               return   null ;
13          }
14          
15           for  (Tuple < Message, Connection >  t : tuples) {
16              Message m  =  t.getKey();
17              Connection con  =  t.getValue();
18               if  (startTransfer(m, con)  ==  RCV_OK) {
19                   return  t;
20              }
21          }
22          
23           return   null;

24     } 

 The function body of MessageRouter::sortByQueueMode:

 1       /**
 2       * Sorts/shuffles the given list according to the current sending queue 
 3       * mode. The list can contain either Message or Tuple<Message, Connection> 
 4       * objects. Other objects cause error. 
 5       *  @param  list The list to sort or shuffle
 6       *  @return  The sorted/shuffled list
 7        */
 8      @SuppressWarnings(value  =   " unchecked " /*  ugly way to make this generic  */
 9       protected  List sortByQueueMode(List list) {
10           switch  (sendQueueMode) {
11           case  Q_MODE_RANDOM:
12              Collections.shuffle(list,  new  Random(SimClock.getIntTime()));
13               break ;
14           case  Q_MODE_FIFO:
15              Collections.sort(list, 
16                       new  Comparator() {
17                   /**  Compares two tuples by their messages' receiving time  */
18                   public   int  compare(Object o1, Object o2) {
19                       double  diff;
20                      Message m1, m2;
21                      
22                       if  (o1  instanceof  Tuple) {
23                          m1  =  ((Tuple < Message, Connection > )o1).getKey();
24                          m2  =  ((Tuple < Message, Connection > )o2).getKey();
25                      }
26                       else   if  (o1  instanceof  Message) {
27                          m1  =  (Message)o1;
28                          m2  =  (Message)o2;
29                      }
30                       else  {
31                           throw   new  SimError( " Invalid type of objects in  "   +  
32                                   " the list " );
33                      }
34                      
35                      diff  =  m1.getReceiveTime()  -  m2.getReceiveTime();
36                       if  (diff  ==   0 ) {
37                           return   0 ;
38                      }
39                       return  (diff  <   0   ?   - 1  :  1 );
40                  }
41              });
42               break ;
43           /*  add more queue modes here  */
44           default :
45               throw   new  SimError( " Unknown queue mode  "   +  sendQueueMode);
46          }
47          
48           return list;

49     }

The function body of ActiveRouter::getMessagesForConnected:

 1       /**
 2       * Returns a list of message-connections tuples of the messages whose
 3       * recipient is some host that we're connected to at the moment.
 4       *  @return  a list of message-connections tuples
 5        */
 6       protected  List < Tuple < Message, Connection >>  getMessagesForConnected() {
 7           if  (getNrofMessages()  ==   0   ||  getConnections().size()  ==   0 ) {
 8               /*  no messages -> empty list  */
 9               return   new  ArrayList < Tuple < Message, Connection >> ( 0 ); 
10          }
11 
12          List < Tuple < Message, Connection >>  forTuples  =  
13               new  ArrayList < Tuple < Message, Connection >> ();
14           for  (Message m : getMessageCollection()) {
15               for  (Connection con : getConnections()) {
16                  DTNHost to  =  con.getOtherNode(getHost());
17                   if  (m.getTo()  ==  to) {
18                      forTuples.add( new  Tuple < Message, Connection > (m,con));
19                  }
20              }
21          }
22          
23           return forTuples;

24     } 

The function body of MessageRouter::requestDeliverableMessages :

1       /**
2       * Requests for deliverable message from this router to be sent trough a
3       * connection.
4       *  @param  con The connection to send the messages trough
5       *  @return  True if this router started a transfer, false if not
6        */
7       public   boolean  requestDeliverableMessages(Connection con) {
8           return   false //  default behavior is to not start -- subclasses override

9     } 

转载于:https://www.cnblogs.com/jcleung/archive/2011/05/31/2064957.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值