github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/workload/faker/faker.go (about)

     1  // Copyright 2019 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package faker
    12  
    13  import "golang.org/x/exp/rand"
    14  
    15  // This is a rough go port of https://github.com/joke2k/faker.
    16  
    17  // Faker returns a generator for random data of various types: names, addresses,
    18  // "lorem ipsum" placeholder text. Faker is safe for concurrent use.
    19  type Faker struct {
    20  	addressFaker
    21  	loremFaker
    22  	nameFaker
    23  }
    24  
    25  // NewFaker returns a new Faker instance. This causes a good amount of
    26  // allocations, so it's best to reuse these when possible.
    27  func NewFaker() Faker {
    28  	f := Faker{
    29  		loremFaker: newLoremFaker(),
    30  		nameFaker:  newNameFaker(),
    31  	}
    32  	f.addressFaker = newAddressFaker(f.nameFaker)
    33  	return f
    34  }
    35  
    36  type weightedEntry struct {
    37  	weight float64
    38  	entry  interface{}
    39  }
    40  
    41  type weightedEntries struct {
    42  	entries     []weightedEntry
    43  	totalWeight float64
    44  }
    45  
    46  func makeWeightedEntries(entriesAndWeights ...interface{}) *weightedEntries {
    47  	we := make([]weightedEntry, 0, len(entriesAndWeights)/2)
    48  	var totalWeight float64
    49  	for idx := 0; idx < len(entriesAndWeights); idx += 2 {
    50  		e, w := entriesAndWeights[idx], entriesAndWeights[idx+1].(float64)
    51  		we = append(we, weightedEntry{weight: w, entry: e})
    52  		totalWeight += w
    53  	}
    54  	return &weightedEntries{entries: we, totalWeight: totalWeight}
    55  }
    56  
    57  func (e *weightedEntries) Rand(rng *rand.Rand) interface{} {
    58  	rngWeight := rng.Float64() * e.totalWeight
    59  	var w float64
    60  	for i := range e.entries {
    61  		w += e.entries[i].weight
    62  		if w > rngWeight {
    63  			return e.entries[i].entry
    64  		}
    65  	}
    66  	panic(`unreachable`)
    67  }
    68  
    69  func randInt(rng *rand.Rand, minInclusive, maxInclusive int) int {
    70  	return rng.Intn(maxInclusive-minInclusive+1) + minInclusive
    71  }