forest-net
an overlay networks for large-scale virtual worlds
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator
RouteTable.cpp
1 
9 #include "RouteTable.h"
10 
11 namespace forest {
12 
13 
18 RouteTable::RouteTable(int maxRtx1, fAdr_t myAdr1, ComtreeTable *ctt1)
19  : maxRtx(maxRtx1), myAdr(myAdr1), ctt(ctt1) {
20  rteMap = new HashMap<uint64_t,Vset,Hash::u64>(maxRtx,false);
21  clMap = new HashMap<uint64_t,Vset,Hash::u64>(maxRtx,false);
22 }
23 
25 RouteTable::~RouteTable() { delete rteMap; delete clMap; }
26 
35 int RouteTable::addRoute(comt_t comt, fAdr_t adr, int cLnk) {
36  Vset links;
37  int rtx = rteMap->put(rmKey(comt,adr),links);
38  if (rtx == 0) return 0;
39  if (cLnk == 0) return rtx;
40  rteMap->getValue(rtx).insert(cLnk);
41  // now update clMap
42  uint64_t kee = cmKey(comt,cLnk);
43  int x = clMap->find(kee);
44  if (x == 0) {
45  Vset new_routes;
46  x = clMap->put(kee,new_routes);
47  }
48  Vset& routes = clMap->getValue(x);
49  routes.insert(rtx);
50  return rtx;
51 }
52 
56 void RouteTable::removeRoute(int rtx) {
57  if (!validRtx(rtx)) return;
58  Vset& lset = rteMap->getValue(rtx);
59  for (int cLnk = lset.first(); cLnk != 0; cLnk = lset.next(cLnk)) {
60  uint64_t kee = cmKey(getComtree(rtx),cLnk);
61  Vset& routes = clMap->get(kee);
62  routes.remove(rtx);
63  if (routes.size() == 0) clMap->remove(kee);
64  }
65  lset.clear();
66  rteMap->remove(rteMap->getKey(rtx));
67 }
68 
75 void RouteTable::purge(comt_t comt, int cLnk) {
76  uint64_t kee = cmKey(comt,cLnk);
77  Vset& routes = clMap->get(kee);
78  for (int rtx = routes.first(); rtx != 0; rtx = routes.next(rtx)) {
79  Vset& lset = rteMap->getValue(rtx);
80  lset.remove(cLnk);
81  if (lset.size() == 0)
82  rteMap->remove(rteMap->getKey(rtx));
83  }
84  routes.clear();
85  clMap->remove(kee);
86 }
87 
98 bool RouteTable::readRoute(istream& in) {
99  int comt, lnk; fAdr_t adr;
100  Util::skipBlank(in);
101  if (!Util::readInt(in, comt) || !Forest::readForestAdr(in,adr))
102  return false;
103  int rtx = addRoute(comt,adr,0);
104  if (rtx == 0) return false;
105  if (Forest::mcastAdr(adr)) {
106  do {
107  if (!Util::readInt(in,lnk)) {
108  removeRoute(rtx); return false;
109  }
110  int cLnk = ctt->getClnkNum(comt,lnk);
111  if (cLnk == 0) return false;
112  addLink(rtx,cLnk);
113  } while (Util::verify(in,','));
114  } else {
115  if (!Util::readInt(in,lnk)) {
116  removeRoute(rtx); return false;
117  }
118  Util::nextLine(in);
119  int cLnk = ctt->getClnkNum(comt,lnk);
120  if (cLnk == 0) return false;
121  setLink(rtx,cLnk);
122  }
123  Util::nextLine(in);
124  return true;
125 }
126 
132 bool RouteTable::read(istream& in) {
133  int num;
134  Util::skipBlank(in);
135  if (!Util::readInt(in,num)) return false;
136  Util::nextLine(in);
137  for (int i = 1; i <= num; i++) {
138  if (!readRoute(in)) {
139  cerr << "Error in route table entry # " << i << endl;
140  return false;
141  }
142  }
143  return true;
144 }
145 
151 string RouteTable::entry2string(int rtx) const {
152  stringstream ss;
153  ss << getComtree(rtx) << " "
154  << Forest::fAdr2string(getAddress(rtx)) << " ";
155  if (noLinks(rtx)) { ss << "-\n"; return ss.str(); }
156  Vset& lset = rteMap->getValue(rtx);
157  for (int cLnk = lset.first(); cLnk != 0; cLnk = lset.next(cLnk)) {
158  if (cLnk != lset.first()) ss << ",";
159  int ctx = ctt->getComtIndex(getComtree(rtx));
160  ss << ctt->getLink(ctx, cLnk);
161  }
162  ss << endl;
163  return ss.str();
164 }
165 
170 string RouteTable::toString() const {
171  stringstream ss;
172  ss << rteMap->size() << endl;
173  for (int rtx = firstRtx(); rtx != 0; rtx = nextRtx(rtx))
174  ss << entry2string(rtx);
175  return ss.str();
176 }
177 
178 } // ends namespace
179