File tree Expand file tree Collapse file tree 1 file changed +21
-12
lines changed
Expand file tree Collapse file tree 1 file changed +21
-12
lines changed Original file line number Diff line number Diff line change @@ -3,7 +3,6 @@ package leaderboard
33import (
44 cryptorand "crypto/rand"
55 "encoding/binary"
6- "math/rand/v2"
76 "sync"
87
98 "gamifykit/core"
@@ -24,37 +23,47 @@ type SkipList struct {
2423 head * node
2524 lvl int
2625 byUser map [core.UserID ]* node
27- rng * rand.Rand
2826}
2927
3028func NewSkipList () * SkipList {
31- // Seed fast PRNG once using crypto/rand; annotated to satisfy gosec.
32- var seed [16 ]byte
33- if _ , err := cryptorand .Read (seed [:]); err != nil {
34- seed = [16 ]byte {}
35- }
36- seed1 := binary .BigEndian .Uint64 (seed [:8 ])
37- seed2 := binary .BigEndian .Uint64 (seed [8 :])
38-
3929 return & SkipList {
4030 head : & node {},
4131 lvl : 1 ,
4232 byUser : map [core.UserID ]* node {},
43- rng : rand .New (rand .NewPCG (seed1 , seed2 )), //nolint:gosec // crypto-seeded PRNG for speed
4433 }
4534}
4635
4736func (s * SkipList ) randomLevel () int {
4837 lvl := 1
38+ bits , err := randomUint64 ()
39+ if err != nil {
40+ return lvl
41+ }
42+
4943 for lvl < maxLevel {
50- if s . rng . Float64 () >= pFactor {
44+ if bits & 0b11 != 0 { // probability 3/4 to stop
5145 break
5246 }
5347 lvl ++
48+ bits >>= 2
49+ if bits == 0 {
50+ bits , err = randomUint64 ()
51+ if err != nil {
52+ break
53+ }
54+ }
5455 }
5556 return lvl
5657}
5758
59+ func randomUint64 () (uint64 , error ) {
60+ var buf [8 ]byte
61+ if _ , err := cryptorand .Read (buf [:]); err != nil {
62+ return 0 , err
63+ }
64+ return binary .LittleEndian .Uint64 (buf [:]), nil
65+ }
66+
5867func less (a , b Entry ) bool {
5968 if a .Score == b .Score {
6069 return a .User < b .User
You can’t perform that action at this time.
0 commit comments