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)