-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathlog_unstable.cc
162 lines (142 loc) · 3.9 KB
/
log_unstable.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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#include "log_unstable.h"
// maybeFirstIndex returns the index of the first possible entry in entries
// if it has a snapshot.
bool unstable::maybeFirstIndex(uint64_t *first)
{
if (snapshot_ != NULL)
{
*first = snapshot_->metadata().index() + 1;
return true;
}
*first = 0;
return false;
}
// maybeLastIndex returns the last index if it has at least one
// unstable entry or snapshot.
bool unstable::maybeLastIndex(uint64_t *last)
{
*last = 0;
if (entries_.size() != 0)
{
*last = offset_ + entries_.size() - 1;
return true;
}
if (snapshot_ != NULL)
{
*last = snapshot_->metadata().index();
return true;
}
return false;
}
// maybeTerm returns the term of the entry at index i, if there
// is any.
bool unstable::maybeTerm(uint64_t i, uint64_t *term)
{
*term = 0;
if (i < offset_)
{
if (snapshot_ == NULL)
{
return false;
}
if (snapshot_->metadata().index() == i)
{
*term = snapshot_->metadata().term();
return true;
}
return false;
}
uint64_t last;
bool ok = maybeLastIndex(&last);
if (!ok)
{
return false;
}
if (i > last)
{
return false;
}
*term = entries_[i - offset_].term();
return true;
}
void unstable::stableTo(uint64_t i, uint64_t t)
{
uint64_t gt;
bool ok = maybeTerm(i, >);
if (!ok)
{
return;
}
// if i < offset, term is matched with the snapshot
// only update the unstable entries if term is matched with
// an unstable entry.
if (gt == t && i >= offset_)
{
entries_.erase(entries_.begin(), entries_.begin() + i + 1 - offset_);
offset_ = i + 1;
//shrinkEntriesArray()
}
}
void unstable::stableSnapTo(uint64_t i)
{
if (snapshot_ != NULL && snapshot_->metadata().index() == i)
{
delete snapshot_;
snapshot_ = NULL;
}
}
void unstable::restore(const Snapshot& snapshot)
{
offset_ = snapshot.metadata().index() + 1;
entries_.clear();
if (snapshot_ == NULL)
{
snapshot_ = new Snapshot();
}
snapshot_->CopyFrom(snapshot);
}
void unstable::truncateAndAppend(const EntryVec& entries)
{
uint64_t after = entries[0].index();
if (after == offset_ + uint64_t(entries_.size()))
{
// after is the next index in the u.entries
// directly append
entries_.insert(entries_.end(), entries.begin(), entries.end());
logger_->Infof(__FILE__, __LINE__, "ENTRY size: %d", entries_.size());
return;
}
if (after <= offset_)
{
// The log is being truncated to before our current offset
// portion, so set the offset and replace the entries
logger_->Infof(__FILE__, __LINE__, "replace the unstable entries from index %llu", after);
offset_ = after;
entries_ = entries;
return;
}
// truncate to after and copy to u.entries then append
logger_->Infof(__FILE__, __LINE__, "truncate the unstable entries before index %llu", after);
vector<Entry> slice;
this->slice(offset_, after, &slice);
entries_ = slice;
entries_.insert(entries_.end(), entries.begin(), entries.end());
}
void unstable::slice(uint64_t lo, uint64_t hi, EntryVec *entries)
{
mustCheckOutOfBounds(lo, hi);
entries->assign(entries_.begin() + lo - offset_, entries_.begin() + hi - offset_);
}
// u.offset <= lo <= hi <= u.offset+len(u.offset)
void unstable::mustCheckOutOfBounds(uint64_t lo, uint64_t hi)
{
if (lo > hi)
{
logger_->Panicf(__FILE__, __LINE__, "invalid unstable.slice %llu > %llu", lo, hi);
}
uint64_t upper = offset_ + (uint64_t)entries_.size();
if (lo < offset_ || upper < hi)
{
logger_->Panicf(__FILE__, __LINE__, "unstable.slice[%llu,%llu) out of bound [%llu,%llu]", lo, hi, offset_, upper);
}
}