github.com/binbinly/pkg@v0.0.11-0.20240321014439-f4fbf666eb0f/util/fastrand.go (about)

     1  package util
     2  
     3  import (
     4  	"math/rand"
     5  	"sync"
     6  	"time"
     7  )
     8  
     9  // Implement Source and Source64 interfaces
    10  type rngSource struct {
    11  	p sync.Pool
    12  }
    13  
    14  func (r *rngSource) Int63() (n int64) {
    15  	src := r.p.Get()
    16  	n = src.(rand.Source).Int63()
    17  	r.p.Put(src)
    18  	return
    19  }
    20  
    21  // Seed specify seed when using NewRand()
    22  func (r *rngSource) Seed(_ int64) {}
    23  
    24  func (r *rngSource) Uint64() (n uint64) {
    25  	src := r.p.Get()
    26  	n = src.(rand.Source64).Uint64()
    27  	r.p.Put(src)
    28  	return
    29  }
    30  
    31  // NewRand goroutine-safe rand.Rand, optional seed value
    32  func NewRand(seed ...int64) *rand.Rand {
    33  	n := time.Now().UnixNano()
    34  	if len(seed) > 0 {
    35  		n = seed[0]
    36  	}
    37  	src := &rngSource{
    38  		p: sync.Pool{
    39  			New: func() any {
    40  				return rand.NewSource(n)
    41  			},
    42  		}}
    43  	return rand.New(src)
    44  }