Skip to content

Commit 9399ee1

Browse files
Merge pull request #140 from nvanbenschoten/nvanbenschoten/lockedSource
Create lockedSource for use by SkipList
2 parents b8c436a + ccfde18 commit 9399ee1

File tree

1 file changed

+24
-6
lines changed

1 file changed

+24
-6
lines changed

slice/skip/skip.go

+24-6
Original file line numberDiff line numberDiff line change
@@ -73,19 +73,37 @@ const p = .5 // the p level defines the probability that a node
7373
// items in the universe. If p = .5 then maxlevel = 32 is appropriate
7474
// for uint32.
7575

76+
// lockedSource is an implementation of rand.Source that is safe for
77+
// concurrent use by multiple goroutines. The code is modeled after
78+
// https://golang.org/src/math/rand/rand.go.
79+
type lockedSource struct {
80+
mu sync.Mutex
81+
src rand.Source
82+
}
83+
84+
// Int63 implements the rand.Source interface.
85+
func (ls *lockedSource) Int63() (n int64) {
86+
ls.mu.Lock()
87+
n = ls.src.Int63()
88+
ls.mu.Unlock()
89+
return
90+
}
91+
92+
// Seed implements the rand.Source interface.
93+
func (ls *lockedSource) Seed(seed int64) {
94+
ls.mu.Lock()
95+
ls.src.Seed(seed)
96+
ls.mu.Unlock()
97+
}
98+
7699
// generator will be the common generator to create random numbers. It
77100
// is seeded with unix nanosecond when this line is executed at runtime,
78101
// and only executed once ensuring all random numbers come from the same
79102
// randomly seeded generator.
80-
var generator = rand.New(rand.NewSource(time.Now().UnixNano()))
81-
82-
// rnLock protects the RNG as the generator is not threadsafe.
83-
var rnLock sync.Mutex
103+
var generator = rand.New(&lockedSource{src: rand.NewSource(time.Now().UnixNano())})
84104

85105
func generateLevel(maxLevel uint8) uint8 {
86106
var level uint8
87-
rnLock.Lock()
88-
defer rnLock.Unlock()
89107
for level = uint8(1); level < maxLevel-1; level++ {
90108
if generator.Float64() >= p {
91109

0 commit comments

Comments
 (0)