Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add/update copyright notices.
[simgrid.git] / examples / lua / SimSplay / chord.lua
1 -- Copyright (c) 2011, 2014. The SimGrid Team.
2 -- All rights reserved.
3
4 -- This program is free software; you can redistribute it and/or modify it
5 -- under the terms of the license (GNU LGPL) which comes with this package.
6
7 dofile "sim_splay.lua"
8 between, call, thread, ping = misc.between_c, rpc.call, events.thread, rpc.ping
9 n, predecessor, finger, timeout, m = {}, nil, {}, 5, 24
10 function join(n0) -- n0: some node in the ring
11         simgrid.info("Euh...")
12         predecessor = nil
13         finger[1] = call(n0, {'find_successor', n.id})
14         simgrid.info("8Here..")
15         call(finger[1], {'notify', n})
16 end
17
18 function closest_preceding_node(id)
19         for i = m, 1, -1 do
20                 if finger[i] and between(finger[i].id, n.id, id) then 
21                         return finger[i]
22                 end
23         end
24         return n
25 end
26
27 function find_successor(id)
28         if finger[1].id == n.id or between(id, n.id, (finger[1].id + 1) % 2^m) then
29                 return finger[1]
30         else
31                 local n0 = closest_preceding_node(id)
32                 return call(n0, {'find_successor', id})
33         end
34 end
35 function stabilize()
36         local x = call(finger[1], 'predecessor')
37         if x and between(x.id, n.id, finger[1].id) then
38                 finger[1] = x -- new successor
39                 call(finger[1], {'notify', n})
40         end
41 end
42 function notify(n0)
43         if n0.id ~= n.id and
44                         (not predecessor or between(n0.id, predecessor.id, n.id)) then
45                 predecessor = n0
46         end
47 end
48 function fix_fingers()
49         refresh = (refresh and (refresh % m) + 1) or 1 -- 1 <= next <= m
50         finger[refresh] = find_successor((n.id + 2^(refresh - 1)) % 2^m)
51 end
52 function check_predecessor()
53         if predecessor and not rpc.ping(predecessor) then
54                 predecessor = nil
55         end
56 end
57
58 n.id = math.random(1, 2^m)
59 finger[1] = n
60 if job then
61         n.ip, n.port = job.me.ip, job.me.port
62         join({ip = "192.42.43.42", port = 20000})
63 else
64         simgrid.info("bizzaaaaaar...")
65         n.ip, n.port = "127.0.0.1", 20000
66         if arg[1] then n.ip = arg[1] end
67         if arg[2] then n.port = tonumber(arg[2]) end
68         if not arg[3] then
69                 print("RDV")
70         else
71                 print("JOIN")
72                 thread(function() join({ip = arg[3], port = tonumber(arg[4])}) end)
73         end
74 end
75 rpc.server(n.port)
76 events.periodic(stabilize, timeout)
77 events.periodic(check_predecessor, timeout)
78 events.periodic(fix_fingers, timeout)
79 events.loop()