Skip to content

Commit

Permalink
fix(utils): speedup random string generation
Browse files Browse the repository at this point in the history
  • Loading branch information
Dmitry Kropachev committed May 30, 2023
1 parent 63cd744 commit 2789e64
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 40 deletions.
4 changes: 2 additions & 2 deletions pkg/coltypes/simple_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,10 @@ func (st SimpleType) GenValue(r *rand.Rand, p *typedef.PartitionRangeConfig) []i
switch st {
case TYPE_ASCII, TYPE_TEXT, TYPE_VARCHAR:
ln := r.Intn(p.MaxStringLength) + p.MinStringLength
val = utils.RandStringWithTime(r, ln, utils.RandTime(r))
val = utils.RandString(r, ln)
case TYPE_BLOB:
ln := r.Intn(p.MaxBlobLength) + p.MinBlobLength
val = hex.EncodeToString([]byte(utils.RandStringWithTime(r, ln, utils.RandTime(r))))
val = hex.EncodeToString([]byte(utils.RandString(r, ln)))
case TYPE_BIGINT:
val = r.Int63()
case TYPE_BOOLEAN:
Expand Down
40 changes: 20 additions & 20 deletions pkg/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,33 +15,15 @@
package utils

import (
"encoding/base64"
"encoding/hex"
"fmt"
"strconv"
"strings"
"time"

"github.com/segmentio/ksuid"
"golang.org/x/exp/rand"
)

func RandStringWithTime(rnd *rand.Rand, len int, t time.Time) string {
id, _ := ksuid.NewRandomWithTime(t)

var buf strings.Builder
buf.WriteString(id.String())
if buf.Len() >= len {
return buf.String()[:len]
}

// Pad some extra random data
buff := make([]byte, len-buf.Len())
_, _ = rnd.Read(buff)
buf.WriteString(base64.StdEncoding.EncodeToString(buff))

return buf.String()[:len]
}

func RandDate(rnd *rand.Rand) string {
return RandTime(rnd).Format("2006-01-02")
}
Expand All @@ -51,7 +33,7 @@ func RandTime(rnd *rand.Rand) time.Time {
max := time.Date(2024, 1, 0, 0, 0, 0, 0, time.UTC).Unix()

sec := rnd.Int63n(max-min) + min
return time.Unix(sec, 0)
return time.Unix(sec, 0).UTC()
}

func RandIpV4Address(rnd *rand.Rand, v, pos int) string {
Expand Down Expand Up @@ -82,3 +64,21 @@ func RandInt(min, max int) int {
func IgnoreError(fn func() error) {
_ = fn()
}

func RandString(rnd *rand.Rand, ln int) string {
buffLen := ln
if buffLen > 32 {
buffLen = 32
}
binBuff := make([]byte, buffLen/2+1)
_, _ = rnd.Read(binBuff)
buff := hex.EncodeToString(binBuff)[:buffLen]
if ln <= 32 {
return buff
}
out := make([]byte, ln+buffLen)
for idx := 0; idx < ln+buffLen; idx += buffLen {
copy(out[idx:], buff)
}
return string(out[:ln])
}
40 changes: 22 additions & 18 deletions pkg/utils/utils_slow_test.go → pkg/utils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,33 +12,37 @@
// See the License for the specific language governing permissions and
// limitations under the License.

//go:build slow
// +build slow

package utils_test

import (
"github.com/scylladb/gemini/pkg/utils"
"golang.org/x/exp/rand"
"testing"
"testing/quick"
"time"

"golang.org/x/exp/rand"

"github.com/scylladb/gemini/pkg/utils"
)

var rnd = rand.New(rand.NewSource(uint64(time.Now().UnixNano())))

func TestNonEmptyRandString(t *testing.T) {
// TODO: Figure out why this is so horribly slow...
tt := time.Now()
f := func(len int32) bool {
if len < 0 {
len = -len
}
r := utils.RandStringWithTime(rnd, int(len), tt)
return r != ""
func BenchmarkUtilsRandString100(t *testing.B) {
for x := 0; x < t.N; x++ {
utils.RandString(rnd, 100)
}
}

func BenchmarkUtilsRandString1000(t *testing.B) {
for x := 0; x < t.N; x++ {
utils.RandString(rnd, 1000)
}
cfg := &quick.Config{MaxCount: 10}
if err := quick.Check(f, cfg); err != nil {
t.Error(err)
}

func TestRandString(t *testing.T) {
for _, ln := range []int{1, 3, 5, 16, 45, 100, 1000} {
out := utils.RandString(rnd, ln)
if len(out) != ln {
t.Fatalf("%d != %d", ln, len(out))
}
println(out)
}
}

0 comments on commit 2789e64

Please sign in to comment.