-
Notifications
You must be signed in to change notification settings - Fork 5
/
utils.go
99 lines (86 loc) · 1.7 KB
/
utils.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
package block_stm
import (
"bytes"
"fmt"
"sync/atomic"
)
type ErrReadError struct {
BlockingTxn TxnIndex
}
func (e ErrReadError) Error() string {
return fmt.Sprintf("read error: blocked by txn %d", e.BlockingTxn)
}
// StoreMin implements a compare-and-swap operation that stores the minimum of the current value and the given value.
func StoreMin(a *atomic.Uint64, b uint64) {
for {
old := a.Load()
if old <= b {
return
}
if a.CompareAndSwap(old, b) {
return
}
}
}
// DecrAtomic decreases the atomic value by 1
func DecrAtomic(a *atomic.Uint64) {
a.Add(^uint64(0))
}
// IncrAtomic increases the atomic value by 1
func IncrAtomic(a *atomic.Uint64) {
a.Add(1)
}
// FetchIncr increaes the atomic value by 1 and returns the old value
func FetchIncr(a *atomic.Uint64) uint64 {
return a.Add(1) - 1
}
// callback arguments: (value, is_new)
func DiffOrderedList(old, new []Key, callback func(Key, bool) bool) {
i, j := 0, 0
for i < len(old) && j < len(new) {
switch bytes.Compare(old[i], new[j]) {
case -1:
if !callback(old[i], false) {
return
}
i++
case 1:
if !callback(new[j], true) {
return
}
j++
default:
i++
j++
}
}
for ; i < len(old); i++ {
if !callback(old[i], false) {
return
}
}
for ; j < len(new); j++ {
if !callback(new[j], true) {
return
}
}
}
// BytesBeyond returns if a is beyond b in specified iteration order
func BytesBeyond(a, b []byte, ascending bool) bool {
if ascending {
return bytes.Compare(a, b) > 0
}
return bytes.Compare(a, b) < 0
}
func BytesIsZero(v []byte) bool {
return v == nil
}
func BytesLen(v []byte) int {
return len(v)
}
func ObjIsZero(v any) bool {
return v == nil
}
func ObjLen(v any) int {
return 1
}