627b7ac62d53cbc351f1cb9961d92d306038f244
[invirt/third/libt4.git] / log.cc
1 #include "paxos.h"
2 #include <fstream>
3 #include <iostream>
4 #include "threaded_log.h"
5
6 // Paxos must maintain some durable state (i.e., that survives power
7 // failures) to run Paxos correct.  This module implements a log with
8 // all durable state to run Paxos.  Since the values chosen correspond
9 // to views, the log contains all views since the beginning of time.
10
11 log::log(acceptor *_acc, std::string _me) : pxs (_acc) {
12     name = "paxos-" + _me + ".log";
13     logread();
14 }
15
16 void log::logread(void) {
17     std::ifstream from;
18     std::string type;
19     unsigned instance;
20
21     from.open(name.c_str());
22     LOG("logread");
23     while (from >> type) {
24         if (type == "done") {
25             std::string v;
26             from >> instance;
27             from.get();
28             getline(from, v);
29             pxs->values[instance] = v;
30             pxs->instance_h = instance;
31             LOG("logread: instance: " << instance << " w. v = " <<
32                     pxs->values[instance]);
33             pxs->v_a.clear();
34             pxs->n_h.n = 0;
35             pxs->n_a.n = 0;
36         } else if (type == "propseen") {
37             from >> pxs->n_h.n;
38             from >> pxs->n_h.m;
39             LOG("logread: high update: " << pxs->n_h.n << "(" << pxs->n_h.m << ")");
40         } else if (type == "accepted") {
41             std::string v;
42             from >> pxs->n_a.n;
43             from >> pxs->n_a.m;
44             from.get();
45             getline(from, v);
46             pxs->v_a = v;
47             LOG("logread: prop update " << pxs->n_a.n << "(" << pxs->n_a.m << ") with v = " << pxs->v_a);
48         } else {
49             LOG("logread: unknown log record");
50             VERIFY(0);
51         }
52     } 
53     from.close();
54 }
55
56 std::string log::dump() {
57     std::ifstream from;
58     std::string res;
59     std::string v;
60     from.open(name.c_str());
61     while (getline(from, v))
62         res += v + "\n";
63     from.close();
64     return res;
65 }
66
67 void log::restore(std::string s) {
68     std::ofstream f;
69     LOG("restore: " << s);
70     f.open(name.c_str(), std::ios::trunc);
71     f << s;
72     f.close();
73 }
74
75 // XXX should be an atomic operation
76 void log::loginstance(unsigned instance, std::string v) {
77     std::ofstream f(name, std::ios::app);
78     f << "done " << instance << " " << v << "\n";
79     f.close();
80 }
81
82 // an acceptor should call logprop(n_h) when it
83 // receives a prepare to which it responds prepare_ok().
84 void log::logprop(prop_t n_h) {
85     std::ofstream f;
86     f.open(name.c_str(), std::ios::app);
87     f << "propseen";
88     f << " ";
89     f << n_h.n;
90     f << " ";
91     f << n_h.m;
92     f << "\n";
93     f.close();
94 }
95
96 // an acceptor should call logaccept(n_a, v_a) when it
97 // receives an accept RPC to which it replies accept_ok().
98 void log::logaccept(prop_t n, std::string v) {
99     std::ofstream f(name, std::ios::app);
100     f << "accepted " << n.n << " " << n.m << " " << v << "\n";
101     f.close();
102 }