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