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