forest-net
an overlay networks for large-scale virtual worlds
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator
RouteTable.h
Go to the documentation of this file.
1 
9 #ifndef ROUTETABLE_H
10 #define ROUTETABLE_H
11 
12 #include <set>
13 #include "Forest.h"
14 #include "Util.h"
15 #include "Hash.h"
16 #include "HashMap.h"
17 #include "ComtreeTable.h"
18 
19 namespace forest {
20 
35 class RouteTable {
36 public:
38  ~RouteTable();
39 
40  // predicates
41  bool validRtx(int) const;
42  bool isLink(int,int) const;
43  bool noLinks(int) const;
44 
45  // iteration methods
46  int firstRtx() const;
47  int nextRtx(int) const;
48  int firstComtLink(int) const;
49  int nextComtLink(int, int) const;
50 
51  // access methods
52  int getRtx(comt_t, fAdr_t) const;
53  comt_t getComtree(int) const;
54  fAdr_t getAddress(int) const;
55  int getLinkCount(int) const;
56 
57  // modifiers
58  bool addLink(int,int);
59  void removeLink(int,int);
60  int addRoute(comt_t,fAdr_t,int);
61  void removeRoute(int);
62  void purge(comt_t, int);
63  void setLink(int,int);
64 
65  // input/output
66  bool read(istream&);
67  string toString() const;
68  string entry2string(int) const;
69 private:
70  int maxRtx;
71  int myAdr;
73 
74  typedef HashSet<int32_t,Hash::s32> Vset;
75 
77  HashMap<uint64_t,Vset,Hash::u64> *rteMap;
78 
79  // map (comtree,link) to list of rtx values (routes that use link)
80  HashMap<uint64_t,Vset,Hash::u64> *clMap;
81 
82  // helper functions
83  uint64_t rmKey(comt_t, fAdr_t) const;
84  uint64_t cmKey(comt_t, int32_t) const;
85  bool readRoute(istream&);
86 };
87 
92 inline bool RouteTable::validRtx(int rtx) const {
93  return rteMap->valid(rtx);
94 }
95 
103 inline bool RouteTable::isLink(int rtx, int cLnk) const {
104  Vset& lset = rteMap->getValue(rtx);
105  return lset.contains(cLnk);
106 }
107 
111 inline bool RouteTable::noLinks(int rtx) const {
112  Vset& lset = rteMap->getValue(rtx);
113  return lset.empty();
114 }
115 
121 inline int RouteTable::firstRtx() const {
122  return rteMap->first();
123 }
124 
131 inline int RouteTable::nextRtx(int rtx) const {
132  return rteMap->next(rtx);
133 }
134 
140 inline int RouteTable::firstComtLink(int rtx) const {
141  return rteMap->getValue(rtx).first();
142 }
143 
152 inline int RouteTable::nextComtLink(int rtx, int cLnk) const {
153  return rteMap->getValue(rtx).next(cLnk);
154 }
155 
161 inline int RouteTable::getRtx(comt_t comt, fAdr_t adr) const {
162  return rteMap->find(rmKey(comt,adr));
163 }
164 
169 inline comt_t RouteTable::getComtree(int rtx) const {
170  uint64_t kee = rteMap->getKey(rtx);
171  return (comt_t) (kee >> 32);
172 }
173 
178 inline fAdr_t RouteTable::getAddress(int rtx) const {
179  uint64_t kee = rteMap->getKey(rtx);
180  return (fAdr_t) (kee & 0xffffffff);
181 }
182 
188 inline int RouteTable::getLinkCount(int rtx) const {
189  return rteMap->getValue(rtx).size();
190 }
191 
197 inline bool RouteTable::addLink(int rtx, int cLnk) {
198  if (!validRtx(rtx) || !Forest::mcastAdr(getAddress(rtx)))
199  return false;
200  Vset& lset = rteMap->getValue(rtx);
201  lset.insert(cLnk);
202  uint64_t kee = cmKey(getComtree(rtx),cLnk);
203  int x = clMap->find(kee);
204  if (x == 0) {
205  Vset new_routes;
206  x = clMap->put(kee,new_routes);
207  }
208  clMap->getValue(x).insert(rtx);
209  return true;
210 }
211 
217 inline void RouteTable::removeLink(int rtx, int cLnk) {
218  if (!validRtx(rtx) || !Forest::mcastAdr(getAddress(rtx)))
219  return;
220  Vset& lset = rteMap->getValue(rtx);
221  lset.remove(cLnk);
222  uint64_t kee = cmKey(getComtree(rtx),cLnk);
223  Vset& routes = clMap->get(kee);
224  routes.remove(rtx);
225  if (lset.size() == 0) // no subscribers left
226  rteMap->remove(rteMap->getKey(rtx));
227  if (routes.size() == 0) // no routes mapped to cLnk
228  clMap->remove(kee);
229 }
230 
235 inline void RouteTable::setLink(int rtx, int cLnk) {
236  if (!validRtx(rtx) || Forest::mcastAdr(getAddress(rtx)))
237  return;
238  // assume link set is empty or has a single member
239  Vset& lset = rteMap->getValue(rtx);
240  if (lset.size() != 0) {
241  int old_cLnk = lset.first();
242  uint64_t kee = cmKey(getComtree(rtx),old_cLnk);
243  Vset& routes = clMap->get(kee);
244  routes.remove(rtx);
245  if (routes.size() == 0) clMap->remove(kee);
246  lset.remove(old_cLnk);
247  }
248  uint64_t kee = cmKey(getComtree(rtx),cLnk);
249  int x = clMap->find(kee);
250  if (x == 0) {
251  Vset new_routes;
252  x = clMap->put(kee,new_routes);
253  }
254  clMap->getValue(x).insert(rtx);
255  lset.insert(cLnk);
256 }
257 
263 inline uint64_t RouteTable::rmKey(comt_t comt, int32_t adr) const {
264  // zero out local address parts for uncast addresses to non-local zip
265  bool local = ((adr & 0xffff0000) ^ (myAdr & 0xffff0000)) == 0;
266  if (!Forest::mcastAdr(adr) && !local) adr &= 0xffff0000;
267  return (uint64_t(comt) << 32) | (uint64_t(adr) & 0xffffffff);
268 }
269 
275 inline uint64_t RouteTable::cmKey(comt_t comt, int32_t cLnk) const {
276  return (uint64_t(comt) << 32) | (uint64_t(cLnk) & 0xffffffff);
277 }
278 
279 } // ends namespace
280 
281 
282 #endif