-
Notifications
You must be signed in to change notification settings - Fork 197
/
int.go
157 lines (139 loc) · 3.45 KB
/
int.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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// Copyright 2014-2022 Aerospike, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package atomic
import (
"strconv"
"sync"
)
// Int implements an int value with atomic semantics
type Int struct {
m sync.Mutex
val int
}
// NewInt generates a newVal Int instance.
func NewInt(value int) *Int {
return &Int{
val: value,
}
}
// String implements the Stringer interface
func (ai *Int) String() string {
res := ai.Get()
return strconv.Itoa(res)
}
// GomegaString implements the GomegaStringer interface
// to prevent race conditions during tests
func (ai *Int) GomegaString() string {
return ai.String()
}
// AddAndGet atomically adds the given value to the current value.
func (ai *Int) AddAndGet(delta int) int {
ai.m.Lock()
ai.val += delta
res := ai.val
ai.m.Unlock()
return res
}
// CloneAndSet atomically clones the atomic Int and sets the value to the given updated value.
func (ai *Int) Clone() Int {
ai.m.Lock()
res := Int{
val: ai.val,
}
ai.m.Unlock()
return res
}
// CloneAndSet atomically clones the atomic Int and sets the value to the given updated value.
func (ai *Int) CloneAndSet(value int) Int {
ai.m.Lock()
res := Int{
val: ai.val,
}
ai.val = value
ai.m.Unlock()
return res
}
// CompareAndSet atomically sets the value to the given updated value if the current value == expected value.
// Returns true if the expectation was met
func (ai *Int) CompareAndSet(expect int, update int) bool {
res := false
ai.m.Lock()
if ai.val == expect {
ai.val = update
res = true
}
ai.m.Unlock()
return res
}
// DecrementAndGet atomically decrements current value by one and returns the result.
func (ai *Int) DecrementAndGet() int {
ai.m.Lock()
ai.val--
res := ai.val
ai.m.Unlock()
return res
}
// Get atomically retrieves the current value.
func (ai *Int) Get() int {
ai.m.Lock()
res := ai.val
ai.m.Unlock()
return res
}
// GetAndAdd atomically adds the given delta to the current value and returns the result.
func (ai *Int) GetAndAdd(delta int) int {
ai.m.Lock()
res := ai.val
ai.val += delta
ai.m.Unlock()
return res
}
// GetAndDecrement atomically decrements the current value by one and returns the result.
func (ai *Int) GetAndDecrement() int {
ai.m.Lock()
res := ai.val
ai.val--
ai.m.Unlock()
return res
}
// GetAndIncrement atomically increments current value by one and returns the result.
func (ai *Int) GetAndIncrement() int {
ai.m.Lock()
res := ai.val
ai.val++
ai.m.Unlock()
return res
}
// GetAndSet atomically sets current value to the given value and returns the old value.
func (ai *Int) GetAndSet(newValue int) int {
ai.m.Lock()
res := ai.val
ai.val = newValue
ai.m.Unlock()
return res
}
// IncrementAndGet atomically increments current value by one and returns the result.
func (ai *Int) IncrementAndGet() int {
ai.m.Lock()
ai.val++
res := ai.val
ai.m.Unlock()
return res
}
// Set atomically sets current value to the given value.
func (ai *Int) Set(newValue int) {
ai.m.Lock()
ai.val = newValue
ai.m.Unlock()
}