Fixed two major bugs in paxos.cc.
[invirt/third/libt4.git] / paxos.h
diff --git a/paxos.h b/paxos.h
index 7188edb..642d3ff 100644 (file)
--- a/paxos.h
+++ b/paxos.h
 #ifndef paxos_h
 #define paxos_h
 
-#include <string>
-#include <vector>
-#include "rpc.h"
+#include "types.h"
+#include "rpc/rpc.h"
 #include "paxos_protocol.h"
 #include "log.h"
-#include "mutex.h"
 
+using prepareres = paxos_protocol::prepareres;
+
+using node_t = string;
+using nodes_t = vector<node_t>;
+using value_t = string;
 
 class paxos_change {
- public:
-  virtual void paxos_commit(unsigned instance, std::string v) = 0;
-  virtual ~paxos_change() {};
+    public:
+        virtual void paxos_commit(unsigned instance, const value_t & v) = 0;
+        virtual ~paxos_change() {}
 };
 
-class acceptor {
- private:
-  log *l;
-  rpcs *pxs;
-  paxos_change *cfg;
-  std::string me;
-  mutex pxs_mutex;
-
-  // Acceptor state
-  prop_t n_h;          // number of the highest proposal seen in a prepare
-  prop_t n_a;          // number of highest proposal accepted
-  std::string v_a;     // value of highest proposal accepted
-  unsigned instance_h; // number of the highest instance we have decided
-  std::map<unsigned,std::string> values;       // vals of each instance
-
-  void commit_wo(unsigned instance, std::string v);
-  paxos_protocol::status preparereq(std::string src, 
-          paxos_protocol::preparearg a,
-          paxos_protocol::prepareres &r);
-  paxos_protocol::status acceptreq(std::string src, 
-          paxos_protocol::acceptarg a, bool &r);
-  paxos_protocol::status decidereq(std::string src, 
-          paxos_protocol::decidearg a, int &r);
-
-  friend class log;
-
- public:
-  acceptor(class paxos_change *cfg, bool _first, std::string _me, 
-       std::string _value);
-  ~acceptor() {};
-  void commit(unsigned instance, std::string v);
-  unsigned instance() { return instance_h; }
-  std::string value(unsigned instance) { return values[instance]; }
-  std::string dump();
-  void restore(std::string);
-  rpcs *get_rpcs() { return pxs; };
-  prop_t get_n_h() { return n_h; };
-  unsigned get_instance_h() { return instance_h; };
-};
+extern bool isamember(const node_t & m, const nodes_t & nodes);
+extern bool majority(const nodes_t & l1, const nodes_t & l2);
 
-extern bool isamember(std::string m, const std::vector<std::string> &nodes);
-extern std::string print_members(const std::vector<std::string> &nodes);
-
-class proposer {
- private:
-  log *l;
-  paxos_change *cfg;
-  acceptor *acc;
-  std::string me;
-  bool break1;
-  bool break2;
-
-  mutex pxs_mutex;
-
-  // Proposer state
-  bool stable;
-  prop_t my_n;         // number of the last proposal used in this instance
-
-  void setn();
-  bool prepare(unsigned instance, std::vector<std::string> &accepts, 
-         std::vector<std::string> nodes,
-         std::string &v);
-  void accept(unsigned instance, std::vector<std::string> &accepts, 
-        std::vector<std::string> nodes, std::string v);
-  void decide(unsigned instance, std::vector<std::string> accepts,
-        std::string v);
-
-  void breakpoint1();
-  void breakpoint2();
-  bool majority(const std::vector<std::string> &l1, const std::vector<std::string> &l2);
-
-  friend class log;
- public:
-  proposer(class paxos_change *cfg, class acceptor *_acceptor, std::string _me);
-  ~proposer() {};
-  bool run(int instance, std::vector<std::string> cnodes, std::string v);
-  bool isrunning();
-  void breakpoint(int b);
-};
+class proposer_acceptor {
+    private:
+        mutex proposer_mutex;
+        mutex acceptor_mutex;
+
+        paxos_change *delegate;
+        node_t me;
+
+        rpcs pxs{(in_port_t)stoi(me)};
+
+        bool break1 = false;
+        bool break2 = false;
+
+        // Proposer state
+        bool stable = true;
+        prop_t proposal = {0, me};  // number of the last proposal used in this instance
 
+        // Acceptor state
+        prop_t promise = {0, me};   // number of the highest proposal seen in a prepare
+        prop_t accepted = {0, me};  // number of highest proposal accepted
+        value_t accepted_value;     // value of highest proposal accepted
+        unsigned instance_h = 0;    // number of the highest instance we have decided
+        map<unsigned,value_t> values;   // vals of each instance
 
+        friend class log;
+        log l = {this, me};
+
+        void commit(unsigned instance, const value_t & v);
+        void commit(unsigned instance, const value_t & v, lock & pxs_mutex_lock);
+
+        paxos_protocol::status preparereq(prepareres & r, const node_t & src, unsigned instance, prop_t n);
+        paxos_protocol::status acceptreq(bool & r, const node_t & src, unsigned instance, prop_t n, const value_t & v);
+        paxos_protocol::status decidereq(int & r, const node_t & src, unsigned instance, const value_t & v);
+
+        bool prepare(unsigned instance, nodes_t & accepts, const nodes_t & nodes, value_t & v);
+        void accept(unsigned instance, nodes_t & accepts, const nodes_t & nodes, const value_t & v);
+        void decide(unsigned instance, const nodes_t & accepts, const value_t & v);
+
+        void breakpoint1();
+        void breakpoint2();
+
+    public:
+        proposer_acceptor(paxos_change *delegate, bool _first, const node_t & _me, const value_t & _value);
+        unsigned instance() { return instance_h; }
+        const value_t & value(unsigned instance) { return values[instance]; }
+        string dump() { return l.dump(); }
+        void restore(const string &s) { l.restore(s); l.logread(); }
+        rpcs *get_rpcs() { return &pxs; }
+
+        bool run(unsigned instance, const nodes_t & cnodes, const value_t & v);
+        bool isrunning() { lock ml(proposer_mutex); return !stable; }
+        void breakpoint(int b);
+};
 
-#endif /* paxos_h */
+#endif