From e1b330bd4290e767a574283fbc7e58999b2f29f3 Mon Sep 17 00:00:00 2001 From: Radu Berinde Date: Tue, 8 Oct 2024 08:48:59 -0700 Subject: [PATCH] internal: remove fastrand This package is no longer necessary, as in `math/rand/v2` the `rand.Uint32` function is equivalent. --- internal/arenaskl/skl.go | 4 +- internal/fastrand/fastrand.go | 17 ----- internal/fastrand/fastrand_test.go | 107 ----------------------------- internal/invariants/utils.go | 4 +- iterator.go | 6 +- 5 files changed, 7 insertions(+), 131 deletions(-) delete mode 100644 internal/fastrand/fastrand.go delete mode 100644 internal/fastrand/fastrand_test.go diff --git a/internal/arenaskl/skl.go b/internal/arenaskl/skl.go index 7f746fef38..0db67e3eff 100644 --- a/internal/arenaskl/skl.go +++ b/internal/arenaskl/skl.go @@ -45,13 +45,13 @@ package arenaskl // import "github.com/cockroachdb/pebble/internal/arenaskl" import ( "math" + "math/rand/v2" "runtime" "sync/atomic" "unsafe" "github.com/cockroachdb/errors" "github.com/cockroachdb/pebble/internal/base" - "github.com/cockroachdb/pebble/internal/fastrand" ) const ( @@ -337,7 +337,7 @@ func (s *Skiplist) newNode( } func (s *Skiplist) randomHeight() uint32 { - rnd := fastrand.Uint32() + rnd := rand.Uint32() h := uint32(1) for h < maxHeight && rnd <= probabilities[h] { diff --git a/internal/fastrand/fastrand.go b/internal/fastrand/fastrand.go deleted file mode 100644 index dd3ec9c84a..0000000000 --- a/internal/fastrand/fastrand.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2020 The LevelDB-Go and Pebble Authors. All rights reserved. Use -// of this source code is governed by a BSD-style license that can be found in -// the LICENSE file. - -package fastrand - -import _ "unsafe" // required by go:linkname - -// Uint32 returns a lock free uint32 value. -// -//go:linkname Uint32 runtime.fastrand -func Uint32() uint32 - -// Uint32n returns a lock free uint32 value in the interval [0, n). -// -//go:linkname Uint32n runtime.fastrandn -func Uint32n(n uint32) uint32 diff --git a/internal/fastrand/fastrand_test.go b/internal/fastrand/fastrand_test.go deleted file mode 100644 index bc12c227ec..0000000000 --- a/internal/fastrand/fastrand_test.go +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2020 The LevelDB-Go and Pebble Authors. All rights reserved. Use -// of this source code is governed by a BSD-style license that can be found in -// the LICENSE file. - -package fastrand - -import ( - "fmt" - "io" - "math/rand/v2" - "sync" - "testing" - "time" -) - -type defaultRand struct { - mu sync.Mutex - src rand.PCG -} - -func newDefaultRand() *defaultRand { - r := &defaultRand{} - r.src.Seed(0, uint64(time.Now().UnixNano())) - return r -} - -func (r *defaultRand) Uint32() uint32 { - r.mu.Lock() - i := uint32(r.src.Uint64()) - r.mu.Unlock() - return i -} - -func BenchmarkFastRand(b *testing.B) { - b.RunParallel(func(pb *testing.PB) { - var x uint32 - for pb.Next() { - x ^= Uint32() - } - fmt.Fprintf(io.Discard, "%v", x) - }) -} - -func BenchmarkRandV2(b *testing.B) { - b.RunParallel(func(pb *testing.PB) { - var x uint32 - for pb.Next() { - x ^= rand.Uint32() - } - fmt.Fprintf(io.Discard, "%v", x) - }) -} - -func BenchmarkDefaultRand(b *testing.B) { - r := newDefaultRand() - b.RunParallel(func(pb *testing.PB) { - for pb.Next() { - r.Uint32() - } - }) -} - -// Benchmarks for single-threaded (ST) use of fastrand compared to -// constructing a Rand, which can have heap allocation overhead. - -// Global state to disable elision of benchmark code. -var xg uint32 - -func BenchmarkSTFastRand(b *testing.B) { - var x uint32 - for i := 0; i < b.N; i++ { - // Arbitrary constant. - x ^= Uint32n(2097152) - } - fmt.Fprintf(io.Discard, "%v", x) -} - -func BenchmarkSTRandV2(b *testing.B) { - var x uint32 - for i := 0; i < b.N; i++ { - // Arbitrary constant. - x ^= rand.Uint32N(2097152) - } - fmt.Fprintf(io.Discard, "%v", x) -} - -func BenchmarkSTDefaultRand(b *testing.B) { - for _, newPeriod := range []int{0, 10, 100, 1000} { - name := "no-new" - if newPeriod > 0 { - name = fmt.Sprintf("new-period=%d", newPeriod) - } - b.Run(name, func(b *testing.B) { - r := rand.New(rand.NewPCG(0, uint64(time.Now().UnixNano()))) - b.ResetTimer() - var x uint32 - for i := 0; i < b.N; i++ { - if newPeriod > 0 && i%newPeriod == 0 { - r = rand.New(rand.NewPCG(0, uint64(time.Now().UnixNano()))) - } - // Arbitrary constant. - x = uint32(r.Uint64N(2097152)) - } - xg = x - }) - } -} diff --git a/internal/invariants/utils.go b/internal/invariants/utils.go index fdcc867641..9faef95f3c 100644 --- a/internal/invariants/utils.go +++ b/internal/invariants/utils.go @@ -4,10 +4,10 @@ package invariants -import "github.com/cockroachdb/pebble/internal/fastrand" +import "math/rand/v2" // Sometimes returns true percent% of the time if we were built with the // "invariants" of "race" build tags func Sometimes(percent int) bool { - return Enabled && fastrand.Uint32()%100 < uint32(percent) + return Enabled && rand.Uint32N(100) < uint32(percent) } diff --git a/iterator.go b/iterator.go index 8fe2f65c3f..29ced18aa7 100644 --- a/iterator.go +++ b/iterator.go @@ -8,13 +8,13 @@ import ( "bytes" "context" "io" + "math/rand/v2" "sync" "unsafe" "github.com/cockroachdb/errors" "github.com/cockroachdb/pebble/internal/base" "github.com/cockroachdb/pebble/internal/bytealloc" - "github.com/cockroachdb/pebble/internal/fastrand" "github.com/cockroachdb/pebble/internal/humanize" "github.com/cockroachdb/pebble/internal/invariants" "github.com/cockroachdb/pebble/internal/keyspan" @@ -810,14 +810,14 @@ func (i *Iterator) maybeSampleRead() { } bytesRead := uint64(len(i.key) + i.value.Len()) for i.readSampling.bytesUntilReadSampling < bytesRead { - i.readSampling.bytesUntilReadSampling += uint64(fastrand.Uint32n(2 * uint32(samplingPeriod))) + i.readSampling.bytesUntilReadSampling += uint64(rand.Uint32N(2 * uint32(samplingPeriod))) // The block below tries to adjust for the case where this is the // first read in a newly-opened iterator. As bytesUntilReadSampling // starts off at zero, we don't want to sample the first read of // every newly-opened iterator, but we do want to sample some of them. if !i.readSampling.initialSamplePassed { i.readSampling.initialSamplePassed = true - if fastrand.Uint32n(uint32(i.readSampling.bytesUntilReadSampling)) > uint32(bytesRead) { + if rand.Uint32N(uint32(i.readSampling.bytesUntilReadSampling)) > uint32(bytesRead) { continue } }