featurebase/bench/sliceheight.go
2017-01-18 20:57:14 -06:00

145 lines
3.5 KiB
Go

package bench
import (
"context"
"flag"
"io"
"io/ioutil"
"strconv"
"time"
"github.com/pilosa/pilosa"
"github.com/pilosa/pilosa/pql"
)
// NewSliceHeight creates a new slice height benchmark with stdin/out/err
// initialized.
func NewSliceHeight(stdin io.Reader, stdout, stderr io.Writer) *SliceHeight {
return &SliceHeight{
Stdin: stdin,
Stdout: stdout,
Stderr: stderr,
}
}
// SliceHeight benchmark tests the effect of an increasing number of bitmaps in
// a single slice on query time.
type SliceHeight struct {
MaxTime time.Duration `json:"max-time"`
hosts []string
Name string `json:"name"`
MinBitsPerMap int64 `json:"min-bits-per-map"`
MaxBitsPerMap int64 `json:"max-bits-per-map"`
Seed int64 `json:"seed"`
Database string `json:"database"`
Frame string `json:"frame"`
Stdin io.Reader `json:"-"`
Stdout io.Writer `json:"-"`
Stderr io.Writer `json:"-"`
}
// Usage returns the usage message to be printed.
func (b *SliceHeight) Usage() string {
return `
slice-height repeatedly imports more bitmaps into a single slice and tests query times in between.
Agent number has no effect on this benchmark.
Usage: slice-height [arguments]
The following arguments are available:
-max-time int
stop benchmark after this many seconds
-min-bits-per-map int
minimum number of bits set per bitmap
-max-bits-per-map int
maximum number of bits set per bitmap
-seed int
seed for RNG
-db string
pilosa db to use
-frame string
frame to import into
`[1:]
}
// ConsumeFlags parses all flags up to the next non flag argument (argument does
// not start with "-" and isn't the value of a flag). It returns the remaining
// args.
func (b *SliceHeight) ConsumeFlags(args []string) ([]string, error) {
fs := flag.NewFlagSet("SliceHeight", flag.ContinueOnError)
fs.SetOutput(ioutil.Discard)
maxTime := fs.Int("max-time", 30, "")
fs.Int64Var(&b.MinBitsPerMap, "min-bits-per-map", 0, "")
fs.Int64Var(&b.MaxBitsPerMap, "max-bits-per-map", 10, "")
fs.Int64Var(&b.Seed, "seed", 0, "")
fs.StringVar(&b.Database, "db", "benchdb", "")
fs.StringVar(&b.Frame, "frame", "testframe", "")
if err := fs.Parse(args); err != nil {
return nil, err
}
b.MaxTime = time.Duration(*maxTime) * time.Second
return fs.Args(), nil
}
// Init sets up the slice height benchmark.
func (b *SliceHeight) Init(hosts []string, agentNum int) error {
b.Name = "slice-height"
b.hosts = hosts
return nil
}
// Run runs the SliceHeight benchmark
func (b *SliceHeight) Run(ctx context.Context) map[string]interface{} {
results := make(map[string]interface{})
imp := NewImport(b.Stdin, b.Stdout, b.Stderr)
imp.MaxBitmapID = 100
imp.MaxProfileID = pilosa.SliceWidth
imp.MinBitsPerMap = b.MinBitsPerMap
imp.MaxBitsPerMap = b.MaxBitsPerMap
imp.Database = b.Database
imp.Frame = b.Frame
start := time.Now()
for i := 0; i > -1; i++ {
iresults := make(map[string]interface{})
results["iteration"+strconv.Itoa(i)] = iresults
genstart := time.Now()
imp.Init(b.hosts, 0)
gendur := time.Now().Sub(genstart)
iresults["csvgen"] = gendur
iresults["import"] = imp.Run(ctx)
qstart := time.Now()
q := &pql.TopN{Frame: b.Frame, N: 50}
_, err := imp.Client.ExecuteQuery(ctx, b.Database, q.String(), true)
if err != nil {
iresults["query_error"] = err.Error()
} else {
qdur := time.Now().Sub(qstart)
iresults["query"] = qdur
}
imp.BaseBitmapID = imp.MaxBitmapID
imp.MaxBitmapID = imp.MaxBitmapID * 10
if time.Now().Sub(start) > b.MaxTime {
break
}
}
return results
}