Mercurial > hg > FederatedLinda
comparison tools/python-PE/CompactRouting/CompactRouting.py @ 8:6c40056777be
Initial revision
author | fuchita |
---|---|
date | Sat, 16 Feb 2008 13:18:02 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
7:1809e2b05824 | 8:6c40056777be |
---|---|
1 from Routing import * | |
2 import time | |
3 | |
4 ROUTING_COMMAND_UPDATE_LANDMARK_TABLE = 5 | |
5 LANDMARK_HOPLIMIT = 2 | |
6 | |
7 class Landmark_TSInfo: | |
8 def __init__(self, landmark_tsid, landmark_dst): | |
9 self.landmark_tsid = landmark_tsid | |
10 self.landmark_dst = landmark_dst | |
11 | |
12 | |
13 """ XML format is as follows | |
14 <RoutingTable name="localhost:10000"> | |
15 <ts hopnum="1" tsid="localhost:10002" ttl="16"/> | |
16 <ts hopnum="1" tsid="localhost:10001" ttl="16"/> | |
17 <ts hopnum="0" tsid="localhost:10000" ttl="0"/> | |
18 <landmark dst="localhost:10000" tsid="localhost:10000"/> | |
19 </RoutingTable> | |
20 """ | |
21 | |
22 class CompactRoutingTable(RoutingTable): | |
23 def __init__(self, name): | |
24 RoutingTable.__init__(self, name) | |
25 self.landmark_tslist = {} | |
26 | |
27 def landmark_register(self, tsid, dst): | |
28 if(self.landmark_tslist.has_key(tsid)): | |
29 del self.landmark_tslist[tsid] | |
30 self.landmark_tslist[tsid] = Landmark_TSInfo(tsid, dst) | |
31 | |
32 def landmark_deregister(self, tsid): | |
33 for t in self.landmark_tslist.keys(): | |
34 # if self.landmark_tslist[t].nexthop == tsid: | |
35 del self.landmark_tslist[t] | |
36 | |
37 def boundedcount_register(self, count): | |
38 self.boundedcount = count | |
39 | |
40 def getNewLandmark(self): | |
41 flag = False | |
42 if(self.landmark_tslist.has_key(self.name)): | |
43 return flag | |
44 | |
45 for t in self.landmark_tslist.keys(): | |
46 landmark_tsid = self.landmark_tslist[t].landmark_tsid | |
47 if(self.tslist.has_key(landmark_tsid)): | |
48 if(self.tslist[landmark_tsid].hopnum == LANDMARK_HOPLIMIT+1): | |
49 flag = True | |
50 else: | |
51 flag = False | |
52 | |
53 return flag | |
54 | |
55 def update(self, xmldoc, ts): | |
56 rt = xml.dom.minidom.parseString(xmldoc).childNodes[0] | |
57 tslist = rt.childNodes | |
58 updateflag = False | |
59 | |
60 tmplist = [] | |
61 | |
62 # append tuplespace | |
63 for t in tslist: | |
64 if t.nodeType == t.ELEMENT_NODE and t.localName == 'ts': | |
65 tsattr = t.attributes | |
66 tsid = tsattr['tsid'].nodeValue | |
67 hopnum = int( tsattr['hopnum'].nodeValue ) | |
68 ttl = int( tsattr['ttl'].nodeValue ) | |
69 nexthop = ts | |
70 | |
71 tmplist.append(tsid) | |
72 | |
73 if (((not self.tslist.has_key(tsid)) or (self.tslist[tsid].hopnum > hopnum+1)) | |
74 and (ttl-1 > 0)): | |
75 self.register(tsid, hopnum+1, ttl-1, nexthop) | |
76 updateflag = True | |
77 | |
78 # delete tuplespace | |
79 for t in self.tslist.values(): | |
80 if (( not t.tsid in tmplist ) and (t.ttl-1 > 0)): | |
81 updateflag = True | |
82 if (t.nexthop == ts): | |
83 del self.tslist[t.tsid] | |
84 | |
85 return updateflag | |
86 | |
87 def update_withLandmark(self, xmldoc, src_ts): | |
88 rt = xml.dom.minidom.parseString(xmldoc).childNodes[0] | |
89 tslist = rt.childNodes | |
90 updateflag = False | |
91 | |
92 tmplist = [] | |
93 tmplandmarklist = [] | |
94 | |
95 for t in tslist: | |
96 # append tuplespace | |
97 if t.nodeType == t.ELEMENT_NODE and t.localName == 'ts': | |
98 tsattr = t.attributes | |
99 tsid = tsattr['tsid'].nodeValue | |
100 hopnum = int( tsattr['hopnum'].nodeValue ) | |
101 ttl = int( tsattr['ttl'].nodeValue ) | |
102 nexthop = src_ts | |
103 | |
104 tmplist.append(tsid) | |
105 if (((not self.tslist.has_key(tsid)) or (self.tslist[tsid].hopnum > hopnum+1)) | |
106 and (ttl-1 > 0)): | |
107 #if ((not self.tslist.has_key(tsid)) or | |
108 # (self.tslist[tsid].hopnum > hopnum+1)): | |
109 self.register(tsid, hopnum+1, ttl-1, nexthop) | |
110 updateflag = True | |
111 | |
112 #parse landmark tsid/dst for register | |
113 elif t.nodeType == t.ELEMENT_NODE and t.localName == 'landmark': | |
114 lkattr = t.attributes | |
115 landmark_tsid = lkattr['tsid'].nodeValue | |
116 landmark_dst = lkattr['dst'].nodeValue | |
117 | |
118 tmplandmarklist.append(landmark_tsid) | |
119 | |
120 if (not self.landmark_tslist.has_key(landmark_tsid)): | |
121 self.landmark_register(landmark_tsid, src_ts) | |
122 updateflag = True | |
123 | |
124 #bounded count -1 | |
125 #elif t.nodeType == t.ELEMENT_NODE and t.localName == 'bound': | |
126 #boundattr = t.attributes | |
127 #if(int(boundattr['count'].nodeValue) > 0): | |
128 # count = int( boundattr['count'].nodeValue)-1 | |
129 # self.boundedcount_register(count) | |
130 # updateflag = True | |
131 #elif(int(boundattr['count'].nodeValue) == 0): | |
132 # self.landmark_register(self.name, self.name) | |
133 # count = int( boundattr['count'].nodeValue)-1 | |
134 # self.boundedcount_register(count) | |
135 # updateflag = True | |
136 | |
137 # delete tuplespace | |
138 for t in self.tslist.values(): | |
139 if (( not t.tsid in tmplist ) and (t.ttl-1 > 0)): | |
140 #if ( not t.tsid in tmplist ): | |
141 updateflag = True | |
142 if (t.nexthop == src_ts): | |
143 del self.tslist[t.tsid] | |
144 | |
145 for lt in self.landmark_tslist.values(): | |
146 if ( not lt.landmark_tsid in tmplandmarklist ): | |
147 updateflag = True | |
148 | |
149 return updateflag | |
150 | |
151 def getxmldoc_withLandmark(self): | |
152 doc = xml.dom.minidom.Document() | |
153 rt = doc.createElement('RoutingTable') | |
154 rt.setAttribute('name', self.name) | |
155 for tskey in self.tslist.keys(): | |
156 #bound limit | |
157 #if(self.tslist[tskey].hopnum < LANDMARK_HOPLIMIT): | |
158 elem = doc.createElement('ts') | |
159 elem.setAttribute('tsid', self.tslist[tskey].tsid) | |
160 elem.setAttribute('hopnum', str(self.tslist[tskey].hopnum)) | |
161 elem.setAttribute('ttl', str(self.tslist[tskey].ttl)) | |
162 rt.appendChild(elem) | |
163 | |
164 for l_tskey in self.landmark_tslist.keys(): | |
165 l_elem = doc.createElement('landmark') | |
166 l_elem.setAttribute('tsid', self.landmark_tslist[l_tskey].landmark_tsid) | |
167 l_elem.setAttribute('dst', self.landmark_tslist[l_tskey].landmark_dst) | |
168 rt.appendChild(l_elem) | |
169 | |
170 #if(self.landmark_tslist.has_key()): | |
171 #bound_elem = doc.createElement('bound') | |
172 #bound_elem.setAttribute('count', str(self.boundedcount)) | |
173 #rt.appendChild(bound_elem) | |
174 | |
175 return rt | |
176 | |
177 def getxml_withLandmark(self): | |
178 rt = self.getxmldoc_withLandmark() | |
179 return rt.toxml() | |
180 | |
181 def getLandmarklist(self, xmltext): | |
182 rt = xml.dom.minidom.parseString(xmltext).childNodes[0] | |
183 landmark = rt.getElementsByTagName('landmark') | |
184 if(landmark.length != 0): | |
185 i = 0 | |
186 while 1: | |
187 try: | |
188 landmark_tsid = landmark[i].getAttribute('tsid') | |
189 landmark_dst = landmark[i].getAttribute('dst') | |
190 print "getLandmarklist",landmark_tsid,landmark_dst | |
191 i = i + 1 | |
192 except IndexError: | |
193 break | |
194 pass | |
195 | |
196 def regLandmarklist(self, xmltext): | |
197 rt = xml.dom.minidom.parseString(xmltext).childNodes[0] | |
198 landmark = rt.getElementsByTagName('landmark') | |
199 if(landmark.length != 0): | |
200 i = 0 | |
201 while 1: | |
202 try: | |
203 landmark_tsid = landmark[i].getAttribute('tsid') | |
204 landmark_dst = landmark[i].getAttribute('dst') | |
205 self.landmark_register(landmark_tsid, landmark_dst) | |
206 i = i + 1 | |
207 except IndexError: | |
208 break | |
209 pass | |
210 | |
211 def printxml_withLandmark(self): | |
212 rt = self.getxmldoc_withLandmark() | |
213 print rt.toprettyxml() | |
214 end = time.time() | |
215 print "passed time ", end | |
216 | |
217 class CompactRouting(Routing): | |
218 def __init__(self, hearderFormat = ROUTING_HEADER_FORMAT): | |
219 Routing.__init__(self, hearderFormat) | |
220 self.landmark_tsid = None | |
221 self.landmark_neighbors = {} | |
222 | |
223 def __del__(self): | |
224 self.linda.close() | |
225 for ts in self.neighbors.values(): | |
226 ts.close() | |
227 for landmark_ts in self.landmark_neighbors.values(): | |
228 landmark_ts.close() | |
229 | |
230 def addLandmark_Neighbor(self, landmark_ts, landmark_tsid): | |
231 self.landmark_neighbors[tsid] = landmark_ts | |
232 return landmark_ts | |
233 | |
234 def delLandmark_Neighbor(self, landmark_ts, landmark_tsid): | |
235 del self.landmark_neighbors[landmark_tsid] | |
236 | |
237 #def landmark_Str2List(self, str_tsidlist): | |
238 #return string.split(str_tsidlist,",") | |
239 | |
240 #def landmark_List2Str(self, landmark_tsidlist): | |
241 #return ",".join(landmark_tsidlist) | |
242 | |
243 # def RoutingConnect(self, data): | |
244 # print "connect" | |
245 # if ( not self.neighbors.has_key(data) ): | |
246 # print "connect2" | |
247 # ts = self.connect(data) | |
248 # ts.Out(TUPLE_ID_ROUTING, self.pack(self.tsid, ROUTING_COMMAND_CONNECT)) | |
249 | |
250 # self.rt.register(data, 1, 3, data) | |
251 # #if (self.rt.landmark_tslist.keys()): | |
252 # # print self.rt.landmark_tslist.keys() | |
253 # upedxml = self.rt.getxml() | |
254 # print "Gen XML ",upedxml | |
255 # print "Neighbors ",self.neighbors | |
256 # for nts in self.neighbors.values(): | |
257 # nts.Out(TUPLE_ID_ROUTING, self.pack(upedxml, ROUTING_COMMAND_UPDATE_TABLE)) | |
258 # pass | |
259 def RoutingConnect(self, data): | |
260 print "connect" | |
261 if ( not self.neighbors.has_key(data) ): | |
262 ts = self.connect(data) | |
263 ts.Out(TUPLE_ID_ROUTING, self.pack(self.tsid, ROUTING_COMMAND_CONNECT)) | |
264 | |
265 self.rt.register(data, 1, LANDMARK_HOPLIMIT, data) | |
266 upedxml = self.rt.getxml() | |
267 # print "Gen XML ",upedxml | |
268 # print "Neighbors ",self.neighbors | |
269 for nts in self.neighbors.values(): | |
270 nts.Out(TUPLE_ID_ROUTING, self.pack(upedxml, ROUTING_COMMAND_UPDATE_TABLE)) | |
271 pass | |
272 | |
273 def RoutingTableUpdate(self,data): | |
274 print "update" | |
275 srcname = self.rt.getdstname(data) | |
276 | |
277 #if ( self.rt.update_withLandmark(data, srcname) ): | |
278 if ( self.rt.update_withLandmark(data, srcname) ): | |
279 #Landmark find | |
280 if(self.rt.getNewLandmark()): | |
281 self.rt.landmark_register(self.rt.name, self.rt.name) | |
282 print "I got New Landmark!" | |
283 # Send Update Info to Neighbors | |
284 upedxml = self.rt.getxml_withLandmark() | |
285 | |
286 #split horizon | |
287 tmp_neighbors = self.neighbors | |
288 del tmp_neighbors[srcname] | |
289 | |
290 for n in tmp_neighbors.values(): | |
291 n.Out(TUPLE_ID_ROUTING, self.pack(upedxml, ROUTING_COMMAND_UPDATE_TABLE)) | |
292 pass | |
293 | |
294 def run(self, mytsid, Landmark_flag): | |
295 self.tsid = mytsid | |
296 hostname, port = string.split(mytsid, ':', 1) | |
297 self.linda = self.flinda.open(hostname, int(port)) | |
298 if not self.linda: | |
299 return | |
300 | |
301 self.rt = CompactRoutingTable(mytsid) | |
302 self.rt.register(self.rt.name, 0, LANDMARK_HOPLIMIT+1, None) | |
303 | |
304 if(Landmark_flag == True): | |
305 self.rt.landmark_register(self.rt.name, self.rt.name) | |
306 | |
307 self.linda.getid() # get client id from Tuple Space (ldserv) | |
308 | |
309 linkConfigReply = self.linda.In(TUPLE_ID_LINKCONFIG) | |
310 routingReply = self.linda.In(TUPLE_ID_ROUTING) | |
311 | |
312 self.flinda.sync() | |
313 | |
314 while(True): | |
315 # Link Configuration | |
316 rep = linkConfigReply.reply() | |
317 if(rep): | |
318 linkConfigReply = self.linda.In(TUPLE_ID_LINKCONFIG) | |
319 | |
320 # Link Configuration main (use Routing class method) | |
321 self.LinkConfig(self.tsid, rep) | |
322 | |
323 # Routing Protocol | |
324 rep = routingReply.reply() | |
325 if(rep): | |
326 routingReply = self.linda.In(TUPLE_ID_ROUTING) | |
327 cmd , data = self.unpack(rep) | |
328 | |
329 # connect to other tuplespace | |
330 if (cmd == ROUTING_COMMAND_CONNECT): | |
331 # connect main | |
332 self.RoutingConnect(data) | |
333 | |
334 # disconnect other tuplespace | |
335 elif (cmd == ROUTING_COMMAND_DISCONNECT): | |
336 # disconnect main | |
337 self.RoutingDisconnect(data) | |
338 | |
339 # update own routing table | |
340 elif (cmd == ROUTING_COMMAND_UPDATE_TABLE): | |
341 #routing table main | |
342 self.RoutingTableUpdate(data) | |
343 | |
344 # transfer tuple | |
345 elif (cmd == ROUTING_COMMAND_TRANSFER): | |
346 # transfer main | |
347 self.RoutingTransfer(data) | |
348 | |
349 else: | |
350 pass | |
351 | |
352 print self.rt.printxml_withLandmark() | |
353 self.flinda.sync() | |
354 #end while | |
355 | |
356 if __name__ == '__main__': | |
357 import sys | |
358 | |
359 Landmark_flag = False | |
360 if (len(sys.argv) != 2) : | |
361 if (sys.argv[2] == "-L"): | |
362 Landmark_flag = True | |
363 else: | |
364 print "Usage : %s <hostname:portnum> or <hostname:portnum> -L" % sys.argv[0] | |
365 sys.exit(1) | |
366 | |
367 mytsid = sys.argv[1] | |
368 | |
369 routing = CompactRouting() | |
370 routing.run(mytsid, Landmark_flag) |