From cb8588228994e70a1df62cea081dd1eb9fc8e68f Mon Sep 17 00:00:00 2001 From: jaffee Date: Mon, 14 Nov 2016 16:57:11 -0600 Subject: [PATCH] add RandomSetBits benchmark demonstrating seeds --- bench/bench.go | 92 +++++++++++++++++++++++++++++++++++++++++++ cmd/pilosactl/main.go | 4 ++ 2 files changed, 96 insertions(+) diff --git a/bench/bench.go b/bench/bench.go index 97a3b048c..cd171e519 100644 --- a/bench/bench.go +++ b/bench/bench.go @@ -12,6 +12,7 @@ import ( "time" "github.com/umbel/pilosa" + "math/rand" ) // Benchmark is an interface to guide the creation of new pilosa benchmarks or @@ -114,6 +115,97 @@ func (b *DiagonalSetBits) Run(agentNum int) map[string]interface{} { return results } +// RandomSetBits sets bits randomly and deterministically based on a seed. +type RandomSetBits struct { + cli *pilosa.Client + BaseBitmapID int64 + BaseProfileID int64 + BitmapIDRange int64 + ProfileIDRange int64 + Iterations int // number of bits that will be set + Seed int64 + DB string // DB to use in pilosa. + +} + +func (b *RandomSetBits) Usage() string { + return ` +RandomSetBits sets random bits + +Usage: RandomSetBits [arguments] + +The following arguments are available: + + -BaseBitmapID int + bitmap id to start from + + -BitmapIDRange int + number of possible bitmap ids that can be set + + -BaseProfileID int + profile id num to start from + + -ProfileIDRange int + number of possible profile ids that can be set + + -Iterations int + number of bits to set + + -Seed int + Seed for RNG + + -DB string + pilosa db to use +`[1:] +} + +func (b *RandomSetBits) ConsumeFlags(args []string) ([]string, error) { + fs := flag.NewFlagSet("RandomSetBits", flag.ContinueOnError) + fs.SetOutput(ioutil.Discard) + fs.Int64Var(&b.BaseBitmapID, "BaseBitmapID", 0, "") + fs.Int64Var(&b.BitmapIDRange, "BitmapIDRange", 100000, "") + fs.Int64Var(&b.BaseProfileID, "BaseProfileID", 0, "") + fs.Int64Var(&b.ProfileIDRange, "ProfileIDRange", 100000, "") + fs.Int64Var(&b.Seed, "Seed", 1, "") + fs.IntVar(&b.Iterations, "Iterations", 100, "") + fs.StringVar(&b.DB, "DB", "benchdb", "") + + if err := fs.Parse(args); err != nil { + return nil, err + } + return fs.Args(), nil +} + +// Init connects to pilosa and sets the client on b. +func (b *RandomSetBits) Init(hosts []string) (err error) { + b.cli, err = pilosa.NewClient(hosts[0]) + if err != nil { + return err + } + if b.DB == "" { + b.DB = "RandomSetBits" + } + return nil +} + +// Run runs the RandomSetBits benchmark +func (b *RandomSetBits) Run(agentNum int) map[string]interface{} { + src := rand.NewSource(b.Seed + int64(agentNum)) + rng := rand.New(src) + results := make(map[string]interface{}) + if b.cli == nil { + results["error"] = fmt.Errorf("No client set for RandomSetBits agent: %v", agentNum) + return results + } + for n := 0; n < b.Iterations; n++ { + bitmapID := rng.Int63n(b.BitmapIDRange) + profID := rng.Int63n(b.ProfileIDRange) + query := fmt.Sprintf("SetBit(%d, 'frame.n', %d)", b.BaseBitmapID+bitmapID, b.BaseProfileID+profID) + b.cli.ExecuteQuery(b.DB, query, true) + } + return results +} + // agentizeNum is a helper which combines the loop iteration (n) with the total // number of iterations and the agentNum in order to produce a globally unique // number across all loop iterations on all agents. diff --git a/cmd/pilosactl/main.go b/cmd/pilosactl/main.go index 7d05671fd..492ec3bfd 100644 --- a/cmd/pilosactl/main.go +++ b/cmd/pilosactl/main.go @@ -1317,6 +1317,8 @@ func (cmd *BagentCommand) ParseFlags(args []string) error { return flag.ErrHelp case "DiagonalSetBits": bm = &bench.DiagonalSetBits{} + case "RandomSetBits": + bm = &bench.RandomSetBits{} default: return fmt.Errorf("Unknown benchmark cmd: %v", remArgs[0]) } @@ -1354,6 +1356,8 @@ The following arguments are available: subcommands: DiagonalSetBits + RandomSetBits + `) }