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

posted @ 2015-01-05 09:49  Ryan in C++  阅读(370)  评论(0编辑  收藏  举报