Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Implement MPI_IN_PLACE behavior for collectives
[simgrid.git] / examples / lua / SimSplay / chord.lua
1 dofile "sim_splay.lua"
2 between, call, thread, ping = misc.between_c, rpc.call, events.thread, rpc.ping
3 n, predecessor, finger, timeout, m = {}, nil, {}, 5, 24
4 function join(n0) -- n0: some node in the ring
5         simgrid.info("Euh...")
6         predecessor = nil
7         finger[1] = call(n0, {'find_successor', n.id})
8         simgrid.info("8Here..")
9         call(finger[1], {'notify', n})
10 end
11
12 function closest_preceding_node(id)
13         for i = m, 1, -1 do
14                 if finger[i] and between(finger[i].id, n.id, id) then 
15                         return finger[i]
16                 end
17         end
18         return n
19 end
20
21 function find_successor(id)
22         if finger[1].id == n.id or between(id, n.id, (finger[1].id + 1) % 2^m) then
23                 return finger[1]
24         else
25                 local n0 = closest_preceding_node(id)
26                 return call(n0, {'find_successor', id})
27         end
28 end
29 function stabilize()
30         local x = call(finger[1], 'predecessor')
31         if x and between(x.id, n.id, finger[1].id) then
32                 finger[1] = x -- new successor
33                 call(finger[1], {'notify', n})
34         end
35 end
36 function notify(n0)
37         if n0.id ~= n.id and
38                         (not predecessor or between(n0.id, predecessor.id, n.id)) then
39                 predecessor = n0
40         end
41 end
42 function fix_fingers()
43         refresh = (refresh and (refresh % m) + 1) or 1 -- 1 <= next <= m
44         finger[refresh] = find_successor((n.id + 2^(refresh - 1)) % 2^m)
45 end
46 function check_predecessor()
47         if predecessor and not rpc.ping(predecessor) then
48                 predecessor = nil
49         end
50 end
51
52 n.id = math.random(1, 2^m)
53 finger[1] = n
54 if job then
55         n.ip, n.port = job.me.ip, job.me.port
56         join({ip = "192.42.43.42", port = 20000})
57 else
58         simgrid.info("bizzaaaaaar...")
59         n.ip, n.port = "127.0.0.1", 20000
60         if arg[1] then n.ip = arg[1] end
61         if arg[2] then n.port = tonumber(arg[2]) end
62         if not arg[3] then
63                 print("RDV")
64         else
65                 print("JOIN")
66                 thread(function() join({ip = arg[3], port = tonumber(arg[4])}) end)
67         end
68 end
69 rpc.server(n.port)
70 events.periodic(stabilize, timeout)
71 events.periodic(check_predecessor, timeout)
72 events.periodic(fix_fingers, timeout)
73 events.loop()