More cleaning
[invirt/third/libt4.git] / paxos.h
1 #ifndef paxos_h
2 #define paxos_h
3
4 #include "types.h"
5 #include "rpc/rpc.h"
6 #include "paxos_protocol.h"
7 #include "log.h"
8
9 using prepareres = paxos_protocol::prepareres;
10
11 using node_t = string;
12 using nodes_t = vector<node_t>;
13 using value_t = string;
14
15 class paxos_change {
16     public:
17         virtual void paxos_commit(unsigned instance, const value_t & v) = 0;
18         virtual ~paxos_change() {}
19 };
20
21 extern bool isamember(const node_t & m, const nodes_t & nodes);
22 extern bool majority(const nodes_t & l1, const nodes_t & l2);
23 extern string print_members(const nodes_t & nodes);
24
25 class proposer_acceptor {
26     private:
27         mutex proposer_mutex;
28         mutex acceptor_mutex;
29
30         paxos_change *delegate;
31         node_t me;
32
33         rpcs pxs = {(uint32_t)std::stoi(me)};
34
35         bool break1 = false;
36         bool break2 = false;
37
38         // Proposer state
39         bool stable = true;
40         prop_t my_n = {0, me};      // number of the last proposal used in this instance
41
42         // Acceptor state
43         prop_t n_h = {0, me};       // number of the highest proposal seen in a prepare
44         prop_t n_a = {0, me};       // number of highest proposal accepted
45         value_t v_a;                // value of highest proposal accepted
46         unsigned instance_h = 0;    // number of the highest instance we have decided
47         map<unsigned,value_t> values;   // vals of each instance
48
49         friend class log;
50         log l = {this, me};
51
52         void commit(unsigned instance, const value_t & v);
53         void commit(unsigned instance, const value_t & v, lock & pxs_mutex_lock);
54
55         paxos_protocol::status preparereq(prepareres & r, const node_t & src, unsigned instance, prop_t n);
56         paxos_protocol::status acceptreq(bool & r, const node_t & src, unsigned instance, prop_t n, const value_t & v);
57         paxos_protocol::status decidereq(int & r, const node_t & src, unsigned instance, const value_t & v);
58
59         bool prepare(unsigned instance, nodes_t & accepts, const nodes_t & nodes, value_t & v);
60         void accept(unsigned instance, nodes_t & accepts, const nodes_t & nodes, const value_t & v);
61         void decide(unsigned instance, const nodes_t & accepts, const value_t & v);
62
63         void breakpoint1();
64         void breakpoint2();
65
66     public:
67         proposer_acceptor(paxos_change *delegate, bool _first, const node_t & _me, const value_t & _value);
68         unsigned instance() { return instance_h; }
69         const value_t & value(unsigned instance) { return values[instance]; }
70         string dump() { return l.dump(); }
71         void restore(const string &s) { l.restore(s); l.logread(); }
72         rpcs *get_rpcs() { return &pxs; }
73
74         bool run(unsigned instance, const nodes_t & cnodes, const value_t & v);
75         bool isrunning() { lock ml(proposer_mutex); return !stable; }
76         void breakpoint(int b);
77 };
78
79 #endif