Skip to content

Commit

Permalink
Merge pull request #553 from SoulPancake/ab/math-rand-v2-mgr
Browse files Browse the repository at this point in the history
feat: Migrate to math/rand/v2
Signed-off-by: Rueian <rueiancsie@gmail.com>
  • Loading branch information
rueian committed Jun 16, 2024
1 parent 5714ec0 commit 6a58272
Show file tree
Hide file tree
Showing 11 changed files with 113 additions and 52 deletions.
5 changes: 2 additions & 3 deletions cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"errors"
"io"
"math/rand"
"net"
"runtime"
"strconv"
Expand Down Expand Up @@ -273,7 +272,7 @@ func (c *clusterClient) _refresh() (err error) {
nodesCount := len(g.nodes)
for _, slot := range g.slots {
for i := slot[0]; i <= slot[1]; i++ {
pslots[i] = conns[g.nodes[1+rand.Intn(nodesCount-1)]].conn
pslots[i] = conns[g.nodes[1+util.FastRand(nodesCount-1)]].conn
}
}
case c.rOpt != nil: // implies c.opt.SendToReplicas != nil
Expand All @@ -284,7 +283,7 @@ func (c *clusterClient) _refresh() (err error) {
for _, slot := range g.slots {
for i := slot[0]; i <= slot[1]; i++ {
pslots[i] = conns[master].conn
rslots[i] = conns[g.nodes[1+rand.Intn(len(g.nodes)-1)]].conn
rslots[i] = conns[g.nodes[1+util.FastRand(len(g.nodes)-1)]].conn
}
}
} else {
Expand Down
25 changes: 25 additions & 0 deletions internal/util/rand.1.22.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//go:build go1.22
// +build go1.22

package util

import (
"encoding/binary"
"math/rand/v2"
)

func Shuffle(n int, swap func(i, j int)) {
rand.Shuffle(n, swap)
}

func FastRand(n int) int {
return rand.IntN(n)
}

func RandomBytes() []byte {
val := make([]byte, 24)
binary.BigEndian.PutUint64(val[0:8], rand.Uint64())
binary.BigEndian.PutUint64(val[8:16], rand.Uint64())
binary.BigEndian.PutUint64(val[16:24], rand.Uint64())
return val
}
44 changes: 44 additions & 0 deletions internal/util/rand.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//go:build !go1.22
// +build !go1.22

package util

import (
"encoding/binary"
"math/rand"
"sync"
"time"
)

var sources sync.Pool

func init() {
sources = sync.Pool{New: func() any { return rand.New(rand.NewSource(time.Now().UnixNano())) }}
}

func Shuffle(n int, swap func(i, j int)) {
rand.Shuffle(n, swap)
}

var rngPool = sync.Pool{
New: func() any {
return rand.New(rand.NewSource(time.Now().UnixNano()))
},
}

func FastRand(n int) (r int) {
s := rngPool.Get().(*rand.Rand)
r = s.Intn(n)
rngPool.Put(s)
return
}

func RandomBytes() []byte {
val := make([]byte, 24)
src := sources.Get().(rand.Source64)
binary.BigEndian.PutUint64(val[0:8], src.Uint64())
binary.BigEndian.PutUint64(val[8:16], src.Uint64())
binary.BigEndian.PutUint64(val[16:24], src.Uint64())
sources.Put(src)
return val
}
30 changes: 30 additions & 0 deletions internal/util/rand_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package util

import (
"testing"
)

func TestShuffle(t *testing.T) {
arr := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
Shuffle(len(arr), func(i, j int) {
arr[i], arr[j] = arr[j], arr[i]
})
if len(arr) != 10 {
t.Errorf("Expected array length 10, got %d", len(arr))
}
}

func TestFastRand(t *testing.T) {
n := 10
res := FastRand(n)
if res < 0 || res >= n {
t.Errorf("Expected result between 0 and %d, got %d", n-1, res)
}
}

func TestRandomBytes(t *testing.T) {
val := RandomBytes()
if len(val) != 24 {
t.Errorf("Expected length 24, got %d", len(val))
}
}
4 changes: 1 addition & 3 deletions mux.go
Original file line number Diff line number Diff line change
Expand Up @@ -401,9 +401,7 @@ var rngPool = sync.Pool{
}

func fastrand(n int) (r int) {
s := rngPool.Get().(*rand.Rand)
r = s.Intn(n)
rngPool.Put(s)
r = util.FastRand(n)
return
}

Expand Down
3 changes: 2 additions & 1 deletion om/hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package om

import (
"context"
"github.com/oklog/ulid/v2"
"reflect"
"strconv"
"time"
Expand Down Expand Up @@ -42,7 +43,7 @@ type HashRepository[T any] struct {
// NewEntity returns an empty entity and will have the `valkey:",key"` field be set with ULID automatically.
func (r *HashRepository[T]) NewEntity() (entity *T) {
var v T
reflect.ValueOf(&v).Elem().Field(r.schema.key.idx).Set(reflect.ValueOf(id()))
reflect.ValueOf(&v).Elem().Field(r.schema.key.idx).Set(reflect.ValueOf(ulid.Make().String()))
return &v
}

Expand Down
3 changes: 2 additions & 1 deletion om/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"strings"
"time"

"github.com/oklog/ulid/v2"
"github.com/valkey-io/valkey-go"
)

Expand Down Expand Up @@ -42,7 +43,7 @@ type JSONRepository[T any] struct {
// NewEntity returns an empty entity and will have the `valkey:",key"` field be set with ULID automatically.
func (r *JSONRepository[T]) NewEntity() *T {
var v T
reflect.ValueOf(&v).Elem().Field(r.schema.key.idx).Set(reflect.ValueOf(id()))
reflect.ValueOf(&v).Elem().Field(r.schema.key.idx).Set(reflect.ValueOf(ulid.Make().String()))
return &v
}

Expand Down
24 changes: 0 additions & 24 deletions om/ulid.go

This file was deleted.

5 changes: 2 additions & 3 deletions sentinel.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ import (
"sync/atomic"
"time"

"math/rand"

"github.com/valkey-io/valkey-go/internal/cmds"
"github.com/valkey-io/valkey-go/internal/util"
)

func newSentinelClient(opt *ClientOption, connFn connFn) (client *sentinelClient, err error) {
Expand Down Expand Up @@ -436,7 +435,7 @@ func pickReplica(resp []ValkeyResult) (string, error) {
}

// choose a replica randomly
m := eligible[rand.Intn(len(eligible))]
m := eligible[util.FastRand(len(eligible))]
return net.JoinHostPort(m["ip"], m["port"]), nil
}

Expand Down
5 changes: 3 additions & 2 deletions valkey.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ import (
"crypto/tls"
"errors"
"math"
"math/rand"
"net"
"runtime"
"strings"
"time"

"github.com/redis/rueidis/internal/util"

Check failure on line 16 in valkey.go

View workflow job for this annotation

GitHub Actions / build (e2e, 1.21.0)

no required module provides package github.com/redis/rueidis/internal/util; to add it:

Check failure on line 16 in valkey.go

View workflow job for this annotation

GitHub Actions / build (e2e, 1.22.0)

no required module provides package github.com/redis/rueidis/internal/util; to add it:

Check failure on line 16 in valkey.go

View workflow job for this annotation

GitHub Actions / build (., 1.22.0)

no required module provides package github.com/redis/rueidis/internal/util; to add it:

Check failure on line 16 in valkey.go

View workflow job for this annotation

GitHub Actions / build (., 1.21.0)

no required module provides package github.com/redis/rueidis/internal/util; to add it:
)

const (
Expand Down Expand Up @@ -332,7 +333,7 @@ func NewClient(option ClientOption) (client Client, err error) {
option.ConnWriteTimeout = option.Dialer.KeepAlive * 10
}
if option.ShuffleInit {
rand.Shuffle(len(option.InitAddress), func(i, j int) {
util.Shuffle(len(option.InitAddress), func(i, j int) {
option.InitAddress[i], option.InitAddress[j] = option.InitAddress[j], option.InitAddress[i]
})
}
Expand Down
17 changes: 2 additions & 15 deletions valkeylock/lock.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,17 @@ package valkeylock

import (
"context"
"encoding/binary"
"errors"
"math/rand"
"strconv"
"strings"
"sync"
"sync/atomic"
"time"

"github.com/valkey-io/valkey-go"
"github.com/valkey-io/valkey-go/internal/util"
)

var sources sync.Pool

func init() {
sources = sync.Pool{New: func() any { return rand.New(rand.NewSource(time.Now().UnixNano())) }}
}

// LockerOption should be passed to NewLocker to construct a Locker
type LockerOption struct {
// ClientBuilder can be used to modify valkey.Client used by Locker
Expand Down Expand Up @@ -140,13 +133,7 @@ func makegate(size int32) *gate {
}

func random() string {
val := make([]byte, 24)
src := sources.Get().(rand.Source64)
binary.BigEndian.PutUint64(val[0:8], src.Uint64())
binary.BigEndian.PutUint64(val[8:16], src.Uint64())
binary.BigEndian.PutUint64(val[16:24], src.Uint64())
sources.Put(src)
return valkey.BinaryString(val)
return valkey.BinaryString(util.RandomBytes())
}

func keyname(prefix, name string, i int32) string {
Expand Down

0 comments on commit 6a58272

Please sign in to comment.