generated from openacid/gotmpl
-
Notifications
You must be signed in to change notification settings - Fork 2
/
log.go
75 lines (56 loc) · 1.42 KB
/
log.go
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
package traft
var (
emptyRecord = &LogRecord{}
)
// a func for test purpose only
func (tr *TRaft) addLogs(cmds ...interface{}) {
me := tr.Status[tr.Id]
for _, cs := range cmds {
cmd := toCmd(cs)
r := tr.addLogInternal(cmd)
me.Accepted.Union(r.Overrides)
}
}
// Only a established leader should use this func.
// no lock protection, must be called from Loop()
func (tr *TRaft) AddLog(cmd *Cmd) *LogRecord {
me := tr.Status[tr.Id]
if me.VotedFor.Id != tr.Id {
panic("wtf")
}
return tr.addLogInternal(cmd)
}
func (tr *TRaft) GetLog(lsn int64) *LogRecord {
idx := lsn - tr.LogOffset
r := tr.Logs[idx]
if r.Seq != lsn {
panic("wtf")
}
return r
}
func (tr *TRaft) addLogInternal(cmd *Cmd) *LogRecord {
me := tr.Status[tr.Id]
lsn := tr.LogOffset + int64(len(tr.Logs))
r := NewRecord(me.VotedFor.Clone(), lsn, cmd)
// find the first interfering record.
var i int
for i = len(tr.Logs) - 1; i >= 0; i-- {
prev := tr.Logs[i]
if r.Interfering(prev) {
r.Overrides = prev.Overrides.Clone()
break
}
}
if i == -1 {
// there is not a interfering record.
r.Overrides = NewTailBitmap(0)
}
r.Overrides.Set(lsn)
// all log I do not know must be executed in order.
// Because I do not know of the intefering relations.
r.Depends = NewTailBitmap(tr.LogOffset)
// reduce bitmap size by removing unknown logs
r.Overrides.Union(NewTailBitmap(tr.LogOffset & ^63))
tr.Logs = append(tr.Logs, r)
return r
}