RINASim  October 2016
Documentation of framework for OMNeT++
DV_Module.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "common/Routing_Alg.h"
4 #include "common/GraphCL.h"
5 
6 namespace common_DVModule {
7 
8 using namespace std;
9 using namespace common_Routing;
10 using namespace common_GraphCL;
11 
12 #define NOCH 0
13 #define CH1OPT 1
14 #define CHMET 2
15 #define CHBOTH 3
16 
17 template<class T>
18 class DV_Module : public Routing_Alg<T> {
19  //Vars and classes
20 public:
21 protected:
22  int secId;
23 
24  struct Entry {
25  set<string> op1, op2;
26  T m1, m2;
27 
28  inline void insert1(const string & dst, const T & m){ op1.insert(dst); m1 = m;}
29  inline void insert2(const string & dst, const T & m){ op2.insert(dst); m2 = m;}
30  inline void erase1(const string & dst){ op1.erase(dst);}
31  inline void erase2(const string & dst){ op2.erase(dst);}
32  inline void clear1(){ op1.clear();}
33  inline void clear2(){ op2.clear();}
34  inline void swap() {T tm = m1; m1 = m2; m2 = tm; set<string> td = op1; op1 = op2; op2 = td; }
35 
36  unsigned char addEntry(const string & dst, const T &m) {
37  if(op1.empty()){
38 
39  insert1(dst, m); return CHBOTH;
40  }else if(op2.empty()){
41  if(op1.find(dst) != op1.end()){
42  if(op1.size() == 1){
43  if(m != m1){
44 
45  insert1(dst, m); return CHBOTH;
46  } else {
47  return NOCH;
48  }
49  } else {
50  if(m < m1){
51 
52  erase1(dst); swap(); insert1(dst, m); return CHBOTH;
53  } else if( m > m1) {
54 
55  erase1(dst); insert2(dst, m); return (op1.size() > 2)? CH1OPT : CHBOTH;
56  } else {
57  return NOCH;
58  }
59  }
60  } else {
61  if(m < m1){
62 
63  swap(); insert1(dst, m); return CHBOTH;
64  } else if( m > m1) {
65 
66  insert2(dst, m); return (op1.size() > 1)? NOCH : CHMET;
67  } else {
68  insert1(dst, m); return CH1OPT;
69  }
70  }
71  } else if(op1.find(dst) != op1.end()){
72  if(op1.size() == 1) {
73  if( m == m1) {
74  return NOCH;
75  } else if( m < m2) {
76 
77  erase1(dst); insert1(dst, m); return CHBOTH;
78  } else if( m == m2) {
79 
80  clear1(); swap(); insert1(dst, m); return CHBOTH;
81  } else {
82 
83  swap(); return CHBOTH;
84  }
85  } else {
86  if(m < m1){
87 
88  erase1(dst); clear2(); swap(); insert1(dst, m); return CHBOTH;
89  } else if( m == m1) {
90  return NOCH;
91  } else if( m < m2) {
92 
93  erase1(dst); clear2(); insert2(dst, m); return (op1.size() > 2)? CH1OPT : CHBOTH;
94  } else if( m == m2) {
95 
96  erase1(dst); insert2(dst, m); return (op1.size() > 2)? CH1OPT : CHBOTH;
97  } else {
98 
99  erase1(dst); return (op1.size() > 2)? CHBOTH : CH1OPT;
100  }
101  }
102  } else if(op2.find(dst) != op2.end()){
103  if(op2.size() == 1) {
104  if(m < m1){
105 
106  swap(); return CHBOTH;
107  } else if( m == m1) {
108 
109  clear2(); insert1(dst, m); return (op1.size() > 2)? CH1OPT : CHBOTH;
110  } else if( m != m2) {
111 
112  insert2(dst, m); return (op1.size() > 1)? NOCH : CHMET;
113  } else {
114  return NOCH;
115  }
116  } else {
117  if(m < m1){
118 
119  clear2(); swap(); insert1(dst, m); return CHBOTH;
120  } else if( m == m1) {
121 
122  erase2(dst); insert1(dst, m); return (op1.size() > 2)? CH1OPT : CHBOTH;
123  } else if( m < m2) {
124 
125  clear2(); insert2(dst, m); return (op1.size() > 1)? NOCH : CHMET;
126  } else if( m == m2) {
127  return NOCH;
128  } else {
129 
130  erase2(dst); return NOCH;
131  }
132  }
133  } else {
134  if(m < m1){
135 
136  clear2(); swap(); insert1(dst, m); return CHBOTH;
137  } else if( m == m1) {
138 
139  insert1(dst, m); return (op1.size() > 2)? CH1OPT : CHBOTH;
140  } else if( m < m2) {
141 
142  clear2(); insert2(dst, m); return (op1.size() > 1)? NOCH : CHMET;
143  } else if( m == m2) {
144 
145  insert2(dst, m); return NOCH;
146  } else {
147  return NOCH;
148  }
149  }
150  return NOCH;
151  }
152 
153  unsigned char removeEntry(const string & dst) {
154  if(op1.find(dst) != op1.end()){
155  if(op1.size() == 1) {
156  clear1(); swap(); return CHBOTH;
157  } else {
158  erase1(dst); return (op1.size() > 2)? CH1OPT : CHBOTH;
159  }
160  } else if(op2.find(dst) != op2.end()){
161  erase2(dst); return (op1.size() > 1)? NOCH : CHMET;
162  } else {
163  return NOCH;
164  }
165  }
166  };
167 
168  struct rtEntry{
169  int sId;
170  map<string, T> entries;
171  rtEntry() : sId(-1){}
172  rtEntry(const int &_sId) : sId(_sId){}
173  };
174 
175  class DV_Update : public Routing_Update {
176  public:
177  string src;
179  DV_Update(const string & s, rtEntry & ent) : src(s), entries(ent) {}
180  };
181 
182  map<string, rtEntry> neiState;
183  map<string, Entry> table;
184 
185  set<string> changed;
186 
187  //Functions
188 public:
189  DV_Module() : secId(-1){}
190  DV_Module(Routing_Module * p, const Address &_nAddr, const string &_addr, T inf) :
191  Routing_Alg<T>(p, _nAddr, _addr, inf), secId(1){}
192 
193  virtual void addSynonym(const string syn) {
195  changed.insert(syn);
196  if(table[syn].addEntry(Routing_Alg<T>::myAddr, 0) & CHMET){
198  }
199  }
200  virtual void removeSynonym(const string syn) {
202  changed.insert(syn);
203  if(table[syn].removeEntry(Routing_Alg<T>::myAddr) & CHMET){
205  }
206  }
207 
208  virtual void addFlow(const Address &_nAddr, const string &_addr, const T &_metric){
209  T oldM = Routing_Alg<T>::nei[_addr];
210  if(oldM == _metric) { return; }
211 
212  Routing_Alg<T>::addFlow(_nAddr, _addr, _metric);
213 
214  unsigned char result = table[_addr].addEntry(_addr, _metric);
215  if(result & CH1OPT) { changed.insert(_addr); }
216 
217  rtEntry * oldE = &neiState[_addr];
218 
219  T Dm = _metric - oldM;
220  for(auto & entry : oldE->entries){
221  entry.second += Dm;
222  unsigned char eResult = table[entry.first].addEntry(_addr, entry.second);
223  if(eResult & CH1OPT) { changed.insert(entry.first); }
224  result |= eResult;
225  }
226 
227  if(result & CHMET) { Routing_Alg<T>::scheduleUpdate(); }
228  }
229 
230  virtual void removeFlow(const Address &_nAddr, const string &_addr){
231  Routing_Alg<T>::removeFlow(_nAddr, _addr);
232 
233  unsigned char result = table[_addr].removeEntry(_addr);
234  if(result & CH1OPT) { changed.insert(_addr); }
235 
236  rtEntry oldE = neiState[_addr];
237 
238  for(const auto & entry : oldE.entries){
239  unsigned char eResult = table[entry.first].removeEntry(_addr);
240  if(eResult & CH1OPT) { changed.insert(entry.first); }
241  result |= eResult;
242  }
243 
244  neiState.erase(_addr);
245 
246  if(result & CHMET) { Routing_Alg<T>::scheduleUpdate(); }
247  }
248 
249  virtual bool processUpdate(Routing_Update * update) {
250  if(DV_Update * up = dynamic_cast<DV_Update*>(update)) {
251  if(up->src == Routing_Alg<T>::myAddr
252  || Routing_Alg<T>::synonyms.find(up->src) != Routing_Alg<T>::synonyms.end()) {
253  return false;
254  }
255 
256 
257 
258  rtEntry oldE = neiState[up->src];
259  if(oldE.sId >= up->entries.sId) { return false; }
260 
261  unsigned char result = 0;
262 
263  for(const auto & entry : up->entries.entries){
264  if(entry.first == Routing_Alg<T>::myAddr) { continue; }
265 
266  unsigned char eResult = table[entry.first].addEntry(up->src, entry.second);
267  if(eResult & CH1OPT) { changed.insert(entry.first); }
268 
269  result |= eResult;
270  }
271 
272  for(const auto & entry : oldE.entries){
273  if(up->entries.entries.find(entry.first) == up->entries.entries.end()){
274  unsigned char eResult = table[entry.first].removeEntry(up->src);
275  if(eResult & CH1OPT) { changed.insert(entry.first); }
276 
277  result |= eResult;
278  }
279  }
280 
281  neiState[up->src] = up->entries;
282 
283  if(result & CHMET){ Routing_Alg<T>::scheduleUpdate(); }
284  return result & CH1OPT;
285  }
286 
287  return false;
288  };
289 
290  virtual void sendUpdate() {
292  secId++;
293 
294  for(auto neig : Routing_Alg<T>::neigTable){
295  T linkM = Routing_Alg<T>::nei[neig.first];
296 
297  rtEntry entry(secId);
298 
299  for(const auto & en : table){
300  if(neig.first == en.first) { continue; }
301  T cMet;
302  bool inform = false;
303  if(en.second.op1.size() >= 2 ) {
304  cMet = en.second.m1;
305  inform = true;
306  } else if(en.second.op1.size() == 1) {
307  if(en.second.op1.find(neig.first) == en.second.op1.end()){
308  cMet = en.second.m1;
309  inform = true;
310  } else if(!en.second.op2.empty()) {
311  cMet = en.second.m2;
312  inform = true;
313  }
314  }
315 
316  if(inform && cMet + linkM < Routing_Alg<T>::infinite){
317  entry.entries[en.first] = cMet + linkM;
318  }
319  }
320 
321  entry.entries[Routing_Alg<T>::myAddr] = linkM;
322  for(const auto & syn : Routing_Alg<T>::synonyms) {
323  entry.entries[syn] = linkM;
324  }
325 
326 
327  Routing_Alg<T>::parent->chSendUpdate(
328  new DV_Update( Routing_Alg<T>::myAddr, entry),
329  neig.second, this);
330  }
331 
332  }
333 
334  virtual map<string, nhLMetric<T> > getChanges() {
335  map<string, nhLMetric<T> > ret;
336  for(const auto & dst : changed) {
337  Entry * e = &table[dst];
338  ret[dst] = nhLMetric<T>(e->m1, e->op1);
339  }
340  changed.clear();
341  return ret;
342  };
343 
344  virtual map<string, nhLMetric<T> > getAll() {
345  map<string, nhLMetric<T> > ret;
346  for(const auto & e : table) {
347  ret[e.first] = nhLMetric<T>(e.second.m1, e.second.op1);
348  }
349  changed.clear();
350  return ret;
351  };
352 
353 
354  virtual void print() {
355  EV << "Print nextHops : "<< endl;
356  for(const auto & e : table) {
357  if(e.second.op1.empty()) { continue; }
358  EV << e.first <<endl;
359  EV << "\t (" << e.second.m1 << ") ::";
360  for (string d : e.second.op1) {
361  EV << " <" << d << ">";
362  }
363  EV <<endl;
364  if(e.second.op2.empty()) { continue; }
365  EV << "\t (" << e.second.m2 << ") ::";
366  for (string d : e.second.op2) {
367  EV << " <" << d << ">";
368  }
369  EV <<endl;
370  }
371 
372 
373  }
374 };
375 
376 } /* namespace common_DVModule */
Definition: DV_Module.h:24
virtual void addFlow(const Address &_nAddr, const string &_addr, const T &_metric)
Definition: DV_Module.h:208
virtual void sendUpdate()
Definition: DV_Module.h:290
unsigned char removeEntry(const string &dst)
Definition: DV_Module.h:153
T m1
Definition: DV_Module.h:26
#define NOCH
Definition: DV_Module.h:12
map< string, T > entries
Definition: DV_Module.h:170
#define CH1OPT
Definition: DV_Module.h:13
virtual void print()
Definition: DV_Module.h:354
map< string, Entry > table
Definition: DV_Module.h:183
#define CHMET
Definition: DV_Module.h:14
virtual map< string, nhLMetric< T > > getChanges()
Definition: DV_Module.h:334
virtual void addSynonym(const string syn)
Definition: DV_Module.h:193
virtual void addSynonym(const string syn)
Definition: Routing_Alg.h:40
set< string > op2
Definition: DV_Module.h:25
#define CHBOTH
Definition: DV_Module.h:15
void clear2()
Definition: DV_Module.h:33
void erase2(const string &dst)
Definition: DV_Module.h:31
unsigned char addEntry(const string &dst, const T &m)
Definition: DV_Module.h:36
virtual void removeSynonym(const string syn)
Definition: Routing_Alg.h:41
void erase1(const string &dst)
Definition: DV_Module.h:30
virtual void removeSynonym(const string syn)
Definition: DV_Module.h:200
virtual void removeFlow(const Address &_nAddr, const string &_addr)
Definition: DV_Module.h:230
void insert2(const string &dst, const T &m)
Definition: DV_Module.h:29
Definition: DV_Module.h:168
map< string, rtEntry > neiState
Definition: DV_Module.h:182
DV_Module(Routing_Module *p, const Address &_nAddr, const string &_addr, T inf)
Definition: DV_Module.h:190
DV_Update(const string &s, rtEntry &ent)
Definition: DV_Module.h:179
rtEntry(const int &_sId)
Definition: DV_Module.h:172
rtEntry()
Definition: DV_Module.h:171
T m2
Definition: DV_Module.h:26
set< string > op1
Definition: DV_Module.h:25
int sId
Definition: DV_Module.h:169
void clear1()
Definition: DV_Module.h:32
void swap()
Definition: DV_Module.h:34
virtual void removeFlow(const Address &_nAddr, const string &_addr)
Definition: Routing_Alg.h:49
virtual bool processUpdate(Routing_Update *update)
Definition: DV_Module.h:249
Address class holds IPC Process identification.
Definition: Address.h:42
virtual map< string, nhLMetric< T > > getAll()
Definition: DV_Module.h:344
virtual void sendUpdate()
Definition: Routing_Alg.h:68
virtual void addFlow(const Address &_nAddr, const string &_addr, const T &_metric)
Definition: Routing_Alg.h:43
void insert1(const string &dst, const T &m)
Definition: DV_Module.h:28