forked from berty/go-ipfs-log
/
lamportclock.go
86 lines (67 loc) · 1.87 KB
/
lamportclock.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
package entry // import "github.com/stateless-minds/go-ipfs-log/entry"
import (
"bytes"
"math"
"github.com/stateless-minds/go-ipfs-log/iface"
)
type LamportClock struct {
ID []byte `json:"id,omitempty"`
Time int `json:"time,omitempty"`
}
func (l *LamportClock) Defined() bool {
return l != nil && len(l.ID) > 0
}
func (l *LamportClock) New() iface.IPFSLogLamportClock {
return &LamportClock{}
}
func (l *LamportClock) SetID(i []byte) {
l.ID = i
}
func (l *LamportClock) SetTime(i int) {
l.Time = i
}
func (l *LamportClock) GetID() []byte {
return l.ID
}
func (l *LamportClock) GetTime() int {
return l.Time
}
// Tick increments the time value, returns a new instance of LamportClock.
func (l *LamportClock) Tick() iface.IPFSLogLamportClock {
l.Time++
return &LamportClock{
ID: l.ID,
Time: l.Time,
}
}
// Merge fusion two LamportClocks.
func (l *LamportClock) Merge(clock iface.IPFSLogLamportClock) iface.IPFSLogLamportClock {
l.Time = int(math.Max(float64(l.Time), float64(clock.GetTime())))
return &LamportClock{
ID: l.ID,
Time: l.Time,
}
}
// Compare calculate the "distance" based on the clock, ie. lower or greater.
func (l *LamportClock) Compare(b iface.IPFSLogLamportClock) int {
// TODO: Make it a Golang slice-compatible sort function
dist := l.Time - b.GetTime()
// If the sequence number is the same (concurrent events),
// return the comparison between IDs
if dist == 0 {
return bytes.Compare(l.ID, b.GetID())
}
return dist
}
// CopyLamportClock returns a copy of a lamport clock
func CopyLamportClock(clock iface.IPFSLogLamportClock) *LamportClock {
return NewLamportClock(clock.GetID(), clock.GetTime())
}
// NewLamportClock creates a new LamportClock instance.
func NewLamportClock(identity []byte, time int) *LamportClock {
return &LamportClock{
ID: identity,
Time: time,
}
}
var _ iface.IPFSLogLamportClock = (*LamportClock)(nil)