-
Notifications
You must be signed in to change notification settings - Fork 54
/
locked_rand.go
138 lines (121 loc) · 3.08 KB
/
locked_rand.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
package rand
import (
"math/rand"
"sync"
)
// LockedRand implements NumberGenerator and embeds Rand that is safe for concurrent use.
type LockedRand struct {
lk sync.Mutex
r *rand.Rand
}
// NewLockedRand creates a new LockedRand that implements all Rand functions that is safe
// for concurrent use.
func NewLockedRand(seed int64) *LockedRand {
return &LockedRand{
r: rand.New(rand.NewSource(seed)),
}
}
// Seed uses the provided seed value to initialize the generator to a deterministic state.
// Seed should not be called concurrently with any other Rand method.
func (lr *LockedRand) Seed(seed int64) {
lr.lk.Lock()
lr.r.Seed(seed)
lr.lk.Unlock()
}
// TwoInt63 generates 2 random int64 without locking twice.
func (lr *LockedRand) TwoInt63() (n1, n2 int64) {
lr.lk.Lock()
n1 = lr.r.Int63()
n2 = lr.r.Int63()
lr.lk.Unlock()
return
}
// Int63 returns a non-negative pseudo-random 63-bit integer as an int64.
func (lr *LockedRand) Int63() (n int64) {
lr.lk.Lock()
n = lr.r.Int63()
lr.lk.Unlock()
return
}
// Uint32 returns a pseudo-random 32-bit value as a uint32.
func (lr *LockedRand) Uint32() (n uint32) {
lr.lk.Lock()
n = lr.r.Uint32()
lr.lk.Unlock()
return
}
// Uint64 returns a pseudo-random 64-bit value as a uint64.
func (lr *LockedRand) Uint64() (n uint64) {
lr.lk.Lock()
n = lr.r.Uint64()
lr.lk.Unlock()
return
}
// Int31 returns a non-negative pseudo-random 31-bit integer as an int32.
func (lr *LockedRand) Int31() (n int32) {
lr.lk.Lock()
n = lr.r.Int31()
lr.lk.Unlock()
return
}
// Int returns a non-negative pseudo-random int.
func (lr *LockedRand) Int() (n int) {
lr.lk.Lock()
n = lr.r.Int()
lr.lk.Unlock()
return
}
// Int63n returns, as an int64, a non-negative pseudo-random number in [0,n).
// It panics if n <= 0.
func (lr *LockedRand) Int63n(n int64) (r int64) {
lr.lk.Lock()
r = lr.r.Int63n(n)
lr.lk.Unlock()
return
}
// Int31n returns, as an int32, a non-negative pseudo-random number in [0,n).
// It panics if n <= 0.
func (lr *LockedRand) Int31n(n int32) (r int32) {
lr.lk.Lock()
r = lr.r.Int31n(n)
lr.lk.Unlock()
return
}
// Intn returns, as an int, a non-negative pseudo-random number in [0,n).
// It panics if n <= 0.
func (lr *LockedRand) Intn(n int) (r int) {
lr.lk.Lock()
r = lr.r.Intn(n)
lr.lk.Unlock()
return
}
// Float64 returns, as a float64, a pseudo-random number in [0.0,1.0).
func (lr *LockedRand) Float64() (n float64) {
lr.lk.Lock()
n = lr.r.Float64()
lr.lk.Unlock()
return
}
// Float32 returns, as a float32, a pseudo-random number in [0.0,1.0).
func (lr *LockedRand) Float32() (n float32) {
lr.lk.Lock()
n = lr.r.Float32()
lr.lk.Unlock()
return
}
// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n).
func (lr *LockedRand) Perm(n int) (r []int) {
lr.lk.Lock()
r = lr.r.Perm(n)
lr.lk.Unlock()
return
}
// Read generates len(p) random bytes and writes them into p. It
// always returns len(p) and a nil error.
// Read should not be called concurrently with any other Rand method.
func (lr *LockedRand) Read(p []byte) (n int, err error) {
lr.lk.Lock()
n, err = lr.r.Read(p)
lr.lk.Unlock()
return
}