zoukankan      html  css  js  c++  java
  • classifier.cc-recv() [ns2.35]

     

      1 //without comments
      2 
      3 int chooseECNSlot()
      4 {
      5     double maxProgress=0;
      6     for(int i=0;i<=nslot_;i++)
      7     { 
      8         if(slot_[i]!=NULL && window_i>2*count)
      9         {
     10             double ti=window_i/(2*count);
     11             double iProg=umap[slot_[i]]+(window_i+ti/2)*ti;
     12             for(int j=0;j<=nslot_;j++)
     13             {
     14                 if(slot_[j]!=NULL && window_j>2*count)
     15                 {
     16                     double jProg=umap[slot_[j]]+(window_j+ti/2)*ti;
     17                     if(jProg>iProg) break;
     18                 }
     19                 if(j==nslot_) 
     20                 {
     21                     return i;
     22                 }
     23             }
     24         }
     25     }//for
     26     return -1;//no flow satisfies the condition.(maybe should return the flow with max progress)
     27 }
     28 
     29 int PortClassifier::recv(Packet* p, Handler*h)
     30 {
     31     NsObject* node = find(p);//find调用classify,classify返回dport。
     32     if (node == NULL) {
     33         Packet::free(p);
     34         return;
     35     }
     36     
     37     umap[node]++;
     38     
     39     if(flag)
     40     {        
     41         hdr_flags *hf=hdr_flags::access(pickPacketForECN(p));
     42         if(hf->ce()==1)
     43         {
     44             hf->ce()=0;
     45             mark=chooseECNSlot();
     46         }
     47         if (mark != -1 &&node==slot_[mark]) 
     48         {
     49             hf->ce()=1;
     50             mark = -1;
     51         }
     52     }//end of flag
     53     
     54     node->recv(p,h);
     55 }
     56       
     57 void PortClassifier::install(int slot, NsObject* p)//install是用来向slot里赋值的。(连接agent & slot)
     58 {
     59     if (slot >= nslot_)
     60         alloc(slot);
     61     slot_[slot] = p;
     62     
     63     if (slot >= maxslot_)
     64         maxslot_ = slot;
     65         
     66     count++;
     67     if(count>=2) 
     68         flag=1;
     69     
     70 }   
     71 
     72    
     73 
     74 ==================================================================================================================================
     75 
     76 15.1.4 rewrite:
     77 
     78 
     79 classifier-port.h里需要添加的:
     80 (1)include处
     81 #include <unordered_map> 还要using namespace std?或者不用?在底下定义的时候用std::unordered_map<NsObject*,double> umap
     82 #include "flags.h"//里面有很多需要的变量和函数,如ce()
     83 (2)3个变量
     84 count=0; flag=0; mark=-1;//可以考虑用复杂些的变量名,防止别的需要include的文件里有重名的
     85 count不止表示agent个数,同时它是server的个数!
     86 flag用来标志receiver;
     87 
     88 //【但是这样全局变量对吗?sender那边如果使用portclassifier时会累加上吗?不会的。这方法可以。亲测有效。】
     89 //【如果不行就用遍历slot的方法。每次遍历一下看有多少agent。】
     90 (3)
     91 unordered_map<NsObject*,double> umap;//看看用不用指定std::
     92 
     93 
     94 
     95 ------------------------------------------------------------------------------------------------------------------------------
     96 //with comments
     97 
     98 int chooseECNSlot()//根据umap里的统计来获取各流进度值。返回值是slot_的下标。
     99 //这个函数还是改成专门筛选流的函数吧(筛选出需要窗口减半的流)
    100 {
    101     //该函数需要能访问到umap以及各流的window大小。
    102     //注意:这里说的按进度排序不是按当前进度排序,而是按下次发生ECN的时刻的进度排序。    
    103     
    104     double maxProgress=0;//初始化最大进度值maxProgress
    105     // mark=-1;//用来标记选中的流
    106     // int flagMax=0;
    107     for(int i=0;i<=nslot_;i++)//下标能否等于nslot?
    108     { //其实遍历slot就行!slot_中有一些是empty,所以虽然知道共有count个agent,还是得完整遍历一遍slot_.
    109         if(slot_[i]!=NULL && window_i>2*count)// 这是能“参赛”的流的入门条件。
    110         {//在window大于2N的流里面找[下次ECN时刻]进度最大的。
    111         //这里count就是server数目N。
    112             //ASSUME flow with index[i] will be the maxProgress-flow at next ECN
    113             double ti=window_i/(2*count);//the time gap from now when next ECN happens
    114             int newProg=umap[slot_[i]]+(window_i+ti/2)*ti;
    115             for(int j=0;j<=nslot_;j++)
    116             {
    117                 if(slot_[j]!=NULL && window_j>2*count)//参赛门槛
    118                 {
    119                     double tj=window_j/(2*count);
    120                     tmpProg=umap[slot_[j]]+(window_j+tj/2)*tj;
    121                     if(tmpProg>newProg) break;//说明i不是下次ecn时进度最快的,假设不成立。
    122                 }
    123             }
    124             // if(umap[slot_[i]]>maxProgress)
    125             // {
    126                 // maxProgress=umap[slot_[i]];//更新maxProgress  
    127                 // mark=i;//标记下该流的node在slot_中对应的下标i;
    128             // }
    129         }
    130         
    131         // else
    132         // {//如果没有window>2N的流,就选当前进度最大的流?这是后话。            
    133         // }
    134         
    135     }//for
    136     
    137     // if(mark!=-1)
    138         return mark;// 返回下标
    139     // else//没有window>2N的流
    140         // return mark2;
    141     
    142 }
    143 
    144 
    145 
    146 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    147 
    148 int PortClassifier::recv(Packet* p, Handler*h)
    149 {
    150     NsObject* node = find(p);//find调用classify,classify返回dport。
    151     if (node == NULL) {
    152         Packet::free(p);
    153         return;
    154     }
    155     
    156     if(flag)//当前node是receiver时才执行下面的算法。
    157     {
    158         // mark=-1;//slot_下标的初始值置为-1?
    159         umap[node]++;//需要在classifier.h中classifier类内部定义unordered_map umap<NsObject*,double>。 (但是注意,当umap里有流已传输完毕后要剔除出去,否则影响排序XXXX如果不用mark2的话那就不会影响到,因为首先是按window来看的,只有window足够大才会看进度。已经传输完成的流window应该变为0吧(如果没变要记得调整))。        
    160         hdr_flags *hf=hdr_flags::access(pickPacketForECN(p));
    161         if(hf->ce()==1)// 说明switch中发生了拥塞
    162         {
    163             hf->ce()=0;//首先清零。然后再根据算法分配ce。
    164             mark=chooseECNSlot();//用chooseECNSlot()选出应当减半的流。
    165         }
    166         
    167         if (mark != -1 &&node==slot_[mark]) //这个recv()程序一开始就用到了find,把packet转换成了agent(这里是用node变量来表示的agent)。所以可以用这个node来和slot_[mark]直接比较。
    168         //对每一个到来的packet都检查,直到发现是mark所标记的那个。可通过portclassifier里的classify返回dport。(参照slideshare P15,为什么通过classifier类,调用的却是portclassifier里的classify ?)
    169         {
    170             hf->ce()=1;
    171             mark = -1;//任务完成,使mark失效。
    172         }
    173     }//end of flag
    174     node->recv(p,h);
    175 }
    176 
    177 
    178 void PortClassifier::install(int slot, NsObject* p)//install是用来向slot里赋值的。(连接agent & slot)
    179 {
    180     if (slot >= nslot_)
    181         alloc(slot);
    182     slot_[slot] = p;
    183     
    184     if (slot >= maxslot_)
    185         maxslot_ = slot;
    186         
    187     count++;
    188     if(count>=2) flag=1;
    189     
    190 }
    191 
    192 
    193 
    194 ==================================================================================================================================
    195 //below is original source code
    196 
    197 void Classifier::recv(Packet* p, Handler*h)//original
    198 {
    199     NsObject* node = find(p);
    200     if (node == NULL) {
    201         /*
    202          * XXX this should be "dropped" somehow.  Right now,
    203          * these events aren't traced.
    204          */
    205         Packet::free(p);
    206         return;
    207     }
    208     
    209     node->recv(p,h);
    210 }
    211 
    212 /////////////////////////////////////////////////////////////////////////////////////////////////////
    213 
    214 void Classifier::install(int slot, NsObject* p)
    215 {
    216     if (slot >= nslot_)
    217         alloc(slot);
    218     slot_[slot] = p;
    219     if (slot >= maxslot_)
    220         maxslot_ = slot;
    221 }
    222 
    223 //above is original source code
    224 ===============================================================================================================

    updated 15.1.8

     1 void Classifier::recv(Packet* p, Handler*h)//original
     2 {
     3     NsObject* node = find(p);
     4     if (node == NULL) {
     5         /*
     6          * XXX this should be "dropped" somehow.  Right now,
     7          * these events aren't traced.
     8          */
     9         Packet::free(p);
    10         return;
    11     }
    12 
    13     node->recv(p,h);
    14 }
    15 
    16 ===============================================================================================================
    17 
    18 int chooseECNSlot()
    19 //这个函数还是改成专门筛选流的函数(筛选出需要窗口减半的流)
    20 {//在打ecn的地方引入调用这个函数,通过该函数来打ECN?或者通过该函数有针对性的回调打ecn的函数。
    21 //该函数需要能访问到umap以及各流的window大小。
    22     
    23     //sort(window)其实不用。用下面的方法只需遍历一次,O(N)复杂度即可。如果sort要O(NlogN)。
    24     int maxProgress=0;//初始化最大进度值maxProgress
    25     int mark=-1;//用来标记选中的流s
    26     for(i=1;i<=n;i++)//其实遍历slot就行!
    27     {
    28         if(window>2*N)//在window大于2N的流里面找进度最大的。(如何获取该流的window?)
    29         {
    30             if(该流的进度值(umap.second)>maxProgress)
    31             {
    32                 maxProgress=该进度值(umap.second);//更新maxProgress  
    33                 mark=i;//标记下该流的node;
    34             }
    35         }
    36         else
    37         {//如果没有window>2N的流,就选当前进度最大的流。
    38             
    39         }
    40     }
    41     if(mark!=-1)
    42         return mark;
    43     else//没有window>2N的流
    44         return mark2;
    45     
    46 }
    47 
    48 
    49 
    50 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    51 15.1.4 rewrite:
    52 
    53 #include "flags.h"//里面有很多需要的变量和函数,如ce()
    54 void Classifier::recv(Packet* p, Handler*h)
    55 {
    56     NsObject* node = find(p);//find调用classify,classify返回dport。
    57     if (node == NULL) {
    58         Packet::free(p);
    59         return;
    60     }
    61     umap[node]++;//需要在classifier.h中classifier类内部定义unordered_map umap<NsObject*,long long int>。 (但是注意,当umap里有流已传输完毕后要剔除出去,否则影响排序XXXX如果不用mark2的话那就不会影响到,因为首先是按window来看的,只有window足够大才会看进度。已经传输完成的流window应该变为0吧(如果没变要记得调整))。
    62     
    63     hdr_flags *hf=hdr_flags::access(pickPacketForECN(p));
    64     if(hf->ce()==1)// 说明switch中发生了拥塞
    65     {
    66         hf->ce()=0;//首先清零。然后再根据算法分配ce。
    67         int mark=function(筛选出需要窗口减半的流的slot下标);//该函数参照上面的chooseECNSlot
    68     }
    69     
    70     if (mark != -1 &&当前packet的dport==slot[mark])//对每一个到来的packet都检查,直到发现是mark所标记的那个。可通过portclassifier里的classify返回dport。(参照slideshare P15,为什么通过classifier类,调用的却是portclassifier里的classify ?)
    71     {
    72         hf->ce()=1;
    73         mark = -1;//使mark失效。
    74     }
    75     node->recv(p,h);
    76 }

     

    http://www.slideshare.net/TBear76/20100403-classifiers

  • 相关阅读:
    动词 + to do、动词 + doing
    图像直线检测——霍夫线变换
    x=min(x, y)
    x=min(x, y)
    算法 Tricks(三)—— 数组(序列)任意区间最小(大)值
    算法 Tricks(三)—— 数组(序列)任意区间最小(大)值
    分治法求解切割篱笆
    分治法求解切割篱笆
    GMM的EM算法实现
    秒杀多线程第二篇 多线程第一次亲热接触 CreateThread与_beginthreadex本质差别
  • 原文地址:https://www.cnblogs.com/forcheryl/p/4202782.html
Copyright © 2011-2022 走看看