-
Notifications
You must be signed in to change notification settings - Fork 13
/
vclock.go
139 lines (118 loc) · 2.75 KB
/
vclock.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
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
package tarantool
import (
"fmt"
"github.com/tinylib/msgp/msgp"
)
// VClock response (in OK).
// Similar to Result struct
type VClock struct {
RequestID uint64 // RequestID is SYNC field;
InstanceID uint32
VClock VectorClock
}
var _ Query = (*VClock)(nil)
// String implements Stringer interface.
func (p *VClock) String() string {
return fmt.Sprintf("VClock ReqID:%v Replica:%v, VClock:%#v",
p.RequestID, p.InstanceID, p.VClock)
}
func (p *VClock) GetCommandID() uint {
return OKCommand
}
func (p *VClock) packMsg(data *packData, b []byte) (o []byte, err error) {
o = b
o = msgp.AppendMapHeader(o, 1)
o = msgp.AppendUint(o, KeyVClock)
o = msgp.AppendMapHeader(o, uint32(len(p.VClock[1:])))
for i, lsn := range p.VClock[1:] {
o = msgp.AppendUint32(o, uint32(i))
o = msgp.AppendUint64(o, lsn)
}
return o, nil
}
// MarshalMsg implements msgp.Marshaler
func (p *VClock) MarshalMsg(b []byte) ([]byte, error) {
return p.packMsg(defaultPackData, b)
}
// UnmarshalMsg implements msgp.Unmarshaller
func (p *VClock) UnmarshalMsg(data []byte) (buf []byte, err error) {
buf = data
if buf, err = p.UnmarshalBinaryHeader(buf); err != nil {
return buf, err
}
if len(buf) == 0 {
return buf, nil
}
return p.UnmarshalBinaryBody(buf)
}
func (p *VClock) UnmarshalBinaryHeader(data []byte) (buf []byte, err error) {
var i uint32
buf = data
if i, buf, err = msgp.ReadMapHeaderBytes(buf); err != nil {
return
}
for ; i > 0; i-- {
var key uint
if key, buf, err = msgp.ReadUintBytes(buf); err != nil {
return
}
switch key {
case KeySync:
if p.RequestID, buf, err = msgp.ReadUint64Bytes(buf); err != nil {
return
}
case KeySchemaID:
if _, buf, err = msgp.ReadUint64Bytes(buf); err != nil {
return
}
case KeyInstanceID:
if p.InstanceID, buf, err = msgp.ReadUint32Bytes(buf); err != nil {
return
}
default:
if buf, err = msgp.Skip(buf); err != nil {
return
}
}
}
return
}
func (p *VClock) UnmarshalBinaryBody(data []byte) (buf []byte, err error) {
var count uint32
buf = data
if count, buf, err = msgp.ReadMapHeaderBytes(buf); err != nil {
return
}
for ; count > 0; count-- {
var key uint
if key, buf, err = msgp.ReadUintBytes(buf); err != nil {
return
}
switch key {
case KeyVClock:
var n uint32
var id uint32
var lsn uint64
if n, buf, err = msgp.ReadMapHeaderBytes(buf); err != nil {
return
}
p.VClock = NewVectorClock()
for ; n > 0; n-- {
if id, buf, err = msgp.ReadUint32Bytes(buf); err != nil {
return
}
if lsn, buf, err = msgp.ReadUint64Bytes(buf); err != nil {
return
}
if !p.VClock.Follow(id, lsn) {
return buf, ErrVectorClock
}
}
default:
if buf, err = msgp.Skip(buf); err != nil {
return
}
}
}
return
}