2018-10-29 01:49:45 +03:00
|
|
|
package server
|
2016-03-05 02:08:16 +03:00
|
|
|
|
2016-03-30 19:32:38 +03:00
|
|
|
import (
|
|
|
|
"errors"
|
2016-12-06 02:24:26 +03:00
|
|
|
"fmt"
|
2016-03-30 19:32:38 +03:00
|
|
|
"math/rand"
|
|
|
|
"strconv"
|
|
|
|
"sync/atomic"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/tidwall/resp"
|
2018-10-11 00:25:40 +03:00
|
|
|
"github.com/tidwall/tile38/internal/log"
|
2016-03-30 19:32:38 +03:00
|
|
|
)
|
|
|
|
|
2016-05-24 00:21:18 +03:00
|
|
|
// MASSINSERT num_keys num_points [minx miny maxx maxy]
|
|
|
|
|
2016-04-04 04:13:33 +03:00
|
|
|
func randMassInsertPosition(minLat, minLon, maxLat, maxLon float64) (float64, float64) {
|
|
|
|
lat, lon := (rand.Float64()*(maxLat-minLat))+minLat, (rand.Float64()*(maxLon-minLon))+minLon
|
|
|
|
return lat, lon
|
|
|
|
}
|
|
|
|
|
2018-10-29 01:49:45 +03:00
|
|
|
func (c *Server) cmdMassInsert(msg *Message) (res resp.Value, err error) {
|
2016-03-30 19:32:38 +03:00
|
|
|
start := time.Now()
|
2018-10-29 01:49:45 +03:00
|
|
|
vs := msg.Args[1:]
|
2016-03-30 19:32:38 +03:00
|
|
|
|
2016-04-04 04:13:33 +03:00
|
|
|
minLat, minLon, maxLat, maxLon := -90.0, -180.0, 90.0, 180.0 //37.10776, -122.67145, 38.19502, -121.62775
|
|
|
|
|
2016-03-30 19:32:38 +03:00
|
|
|
var snumCols, snumPoints string
|
|
|
|
var cols, objs int
|
|
|
|
var ok bool
|
|
|
|
if vs, snumCols, ok = tokenval(vs); !ok || snumCols == "" {
|
2018-10-29 01:49:45 +03:00
|
|
|
return NOMessage, errInvalidNumberOfArguments
|
2016-03-30 19:32:38 +03:00
|
|
|
}
|
|
|
|
if vs, snumPoints, ok = tokenval(vs); !ok || snumPoints == "" {
|
2018-10-29 01:49:45 +03:00
|
|
|
return NOMessage, errInvalidNumberOfArguments
|
2016-03-30 19:32:38 +03:00
|
|
|
}
|
|
|
|
if len(vs) != 0 {
|
2016-04-04 04:13:33 +03:00
|
|
|
var sminLat, sminLon, smaxLat, smaxLon string
|
|
|
|
if vs, sminLat, ok = tokenval(vs); !ok || sminLat == "" {
|
2018-10-29 01:49:45 +03:00
|
|
|
return NOMessage, errInvalidNumberOfArguments
|
2016-04-04 04:13:33 +03:00
|
|
|
}
|
|
|
|
if vs, sminLon, ok = tokenval(vs); !ok || sminLon == "" {
|
2018-10-29 01:49:45 +03:00
|
|
|
return NOMessage, errInvalidNumberOfArguments
|
2016-04-04 04:13:33 +03:00
|
|
|
}
|
|
|
|
if vs, smaxLat, ok = tokenval(vs); !ok || smaxLat == "" {
|
2018-10-29 01:49:45 +03:00
|
|
|
return NOMessage, errInvalidNumberOfArguments
|
2016-04-04 04:13:33 +03:00
|
|
|
}
|
|
|
|
if vs, smaxLon, ok = tokenval(vs); !ok || smaxLon == "" {
|
2018-10-29 01:49:45 +03:00
|
|
|
return NOMessage, errInvalidNumberOfArguments
|
2016-04-04 04:13:33 +03:00
|
|
|
}
|
|
|
|
var err error
|
|
|
|
if minLat, err = strconv.ParseFloat(sminLat, 64); err != nil {
|
2018-10-29 01:49:45 +03:00
|
|
|
return NOMessage, err
|
2016-04-04 04:13:33 +03:00
|
|
|
}
|
|
|
|
if minLon, err = strconv.ParseFloat(sminLon, 64); err != nil {
|
2018-10-29 01:49:45 +03:00
|
|
|
return NOMessage, err
|
2016-04-04 04:13:33 +03:00
|
|
|
}
|
|
|
|
if maxLat, err = strconv.ParseFloat(smaxLat, 64); err != nil {
|
2018-10-29 01:49:45 +03:00
|
|
|
return NOMessage, err
|
2016-04-04 04:13:33 +03:00
|
|
|
}
|
|
|
|
if maxLon, err = strconv.ParseFloat(smaxLon, 64); err != nil {
|
2018-10-29 01:49:45 +03:00
|
|
|
return NOMessage, err
|
2016-04-04 04:13:33 +03:00
|
|
|
}
|
|
|
|
if len(vs) != 0 {
|
2018-10-29 01:49:45 +03:00
|
|
|
return NOMessage, errors.New("invalid number of arguments")
|
2016-04-04 04:13:33 +03:00
|
|
|
}
|
2016-03-30 19:32:38 +03:00
|
|
|
}
|
|
|
|
n, err := strconv.ParseUint(snumCols, 10, 64)
|
|
|
|
if err != nil {
|
2018-10-29 01:49:45 +03:00
|
|
|
return NOMessage, errInvalidArgument(snumCols)
|
2016-03-30 19:32:38 +03:00
|
|
|
}
|
|
|
|
cols = int(n)
|
|
|
|
n, err = strconv.ParseUint(snumPoints, 10, 64)
|
|
|
|
if err != nil {
|
2018-10-29 01:49:45 +03:00
|
|
|
return NOMessage, errInvalidArgument(snumPoints)
|
2016-03-30 19:32:38 +03:00
|
|
|
}
|
2019-09-04 02:35:42 +03:00
|
|
|
|
|
|
|
type docmdDetails struct {
|
|
|
|
writeAOFDetails writeAOFDetails
|
|
|
|
cmdElapsed time.Duration
|
|
|
|
aofElapsed time.Duration
|
|
|
|
}
|
|
|
|
|
|
|
|
docmd := func(args []string) (docmdDetails docmdDetails, err error) {
|
|
|
|
c.mu.Lock()
|
|
|
|
defer c.mu.Unlock()
|
2018-12-04 01:35:32 +03:00
|
|
|
var nmsg Message
|
|
|
|
nmsg = *msg
|
|
|
|
nmsg._command = ""
|
2018-10-29 01:49:45 +03:00
|
|
|
nmsg.Args = args
|
2018-11-24 01:53:33 +03:00
|
|
|
var d commandDetails
|
2019-09-04 02:35:42 +03:00
|
|
|
start := time.Now()
|
2018-12-04 01:35:32 +03:00
|
|
|
_, d, err = c.command(&nmsg, nil)
|
2019-09-04 02:35:42 +03:00
|
|
|
docmdDetails.cmdElapsed = time.Since(start)
|
2016-03-30 19:32:38 +03:00
|
|
|
if err != nil {
|
2019-09-04 02:35:42 +03:00
|
|
|
return docmdDetails, err
|
2016-03-30 19:32:38 +03:00
|
|
|
}
|
2019-09-04 02:35:42 +03:00
|
|
|
start = time.Now()
|
|
|
|
docmdDetails.writeAOFDetails, err = c.writeAOFDetails(nmsg.Args, &d)
|
|
|
|
docmdDetails.aofElapsed = time.Since(start)
|
|
|
|
return docmdDetails, err
|
2018-10-29 01:49:45 +03:00
|
|
|
|
2016-03-30 19:32:38 +03:00
|
|
|
}
|
|
|
|
rand.Seed(time.Now().UnixNano())
|
|
|
|
objs = int(n)
|
|
|
|
var k uint64
|
|
|
|
for i := 0; i < cols; i++ {
|
|
|
|
key := "mi:" + strconv.FormatInt(int64(i), 10)
|
2016-12-06 02:24:26 +03:00
|
|
|
func(key string) {
|
|
|
|
// lock cycle
|
2016-03-30 19:32:38 +03:00
|
|
|
for j := 0; j < objs; j++ {
|
|
|
|
id := strconv.FormatInt(int64(j), 10)
|
2018-10-29 01:49:45 +03:00
|
|
|
var values []string
|
2019-02-12 01:42:35 +03:00
|
|
|
values = append(values, "set", key, id)
|
|
|
|
fvals := []float64{
|
|
|
|
1, // one
|
|
|
|
0, // zero
|
|
|
|
-1, // negOne
|
|
|
|
14, // nibble
|
|
|
|
20.5, // tinyDiv10
|
|
|
|
120, // int8
|
|
|
|
-120, // int8
|
|
|
|
20000, // int16
|
|
|
|
-20000, // int16
|
|
|
|
214748300, // int32
|
|
|
|
-214748300, // int32
|
|
|
|
2014748300, // float64
|
|
|
|
123.12312301, // float64
|
|
|
|
}
|
|
|
|
for i, fval := range fvals {
|
|
|
|
values = append(values, "FIELD",
|
|
|
|
fmt.Sprintf("fname:%d", i),
|
|
|
|
strconv.FormatFloat(fval, 'f', -1, 64))
|
|
|
|
}
|
2016-12-06 02:24:26 +03:00
|
|
|
if j%8 == 0 {
|
2019-02-12 01:42:35 +03:00
|
|
|
values = append(values, "STRING", fmt.Sprintf("str%v", j))
|
2016-12-06 20:30:48 +03:00
|
|
|
} else {
|
2016-12-06 02:24:26 +03:00
|
|
|
lat, lon := randMassInsertPosition(minLat, minLon, maxLat, maxLon)
|
2018-10-29 01:49:45 +03:00
|
|
|
values = append(values, "POINT",
|
|
|
|
strconv.FormatFloat(lat, 'f', -1, 64),
|
|
|
|
strconv.FormatFloat(lon, 'f', -1, 64),
|
|
|
|
)
|
2016-03-30 19:32:38 +03:00
|
|
|
}
|
2019-09-04 02:35:42 +03:00
|
|
|
start := time.Now()
|
|
|
|
docmdDetails, err := docmd(values)
|
|
|
|
if err != nil {
|
2016-03-30 19:32:38 +03:00
|
|
|
log.Fatal(err)
|
|
|
|
return
|
|
|
|
}
|
2019-09-04 02:35:42 +03:00
|
|
|
elapsed := time.Since(start)
|
|
|
|
if elapsed > time.Millisecond*5 {
|
|
|
|
log.Infof("%d"+
|
|
|
|
", %6.1f cmd, %6.1f aof"+
|
|
|
|
", %6.1f buf, %6.1f not, %6.1f fence"+
|
|
|
|
", %6.1f tot",
|
|
|
|
len(values),
|
|
|
|
docmdDetails.cmdElapsed.Seconds()*1000,
|
|
|
|
docmdDetails.aofElapsed.Seconds()*1000,
|
|
|
|
docmdDetails.writeAOFDetails.appendBufferElapsed.Seconds()*1000,
|
|
|
|
docmdDetails.writeAOFDetails.notifyLiveElapsed.Seconds()*1000,
|
|
|
|
docmdDetails.writeAOFDetails.geofencesElapsed.Seconds()*1000,
|
|
|
|
elapsed.Seconds()*1000,
|
|
|
|
)
|
|
|
|
}
|
2016-03-30 19:32:38 +03:00
|
|
|
atomic.AddUint64(&k, 1)
|
2016-12-06 02:24:26 +03:00
|
|
|
if j%1000 == 1000-1 {
|
2019-09-04 02:35:42 +03:00
|
|
|
log.Debugf("mass: %s %d/%d",
|
|
|
|
key, atomic.LoadUint64(&k), cols*objs)
|
2016-03-30 19:32:38 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}(key)
|
|
|
|
}
|
|
|
|
log.Infof("massinsert: done %d objects", atomic.LoadUint64(&k))
|
2018-10-29 01:49:45 +03:00
|
|
|
return OKMessage(msg, start), nil
|
2016-03-05 02:08:16 +03:00
|
|
|
}
|
2017-09-30 18:11:10 +03:00
|
|
|
|
2018-10-29 01:49:45 +03:00
|
|
|
func (c *Server) cmdSleep(msg *Message) (res resp.Value, err error) {
|
2017-09-30 18:11:10 +03:00
|
|
|
start := time.Now()
|
2018-10-29 01:49:45 +03:00
|
|
|
if len(msg.Args) != 2 {
|
|
|
|
return NOMessage, errInvalidNumberOfArguments
|
2017-09-30 18:11:10 +03:00
|
|
|
}
|
2018-10-29 01:49:45 +03:00
|
|
|
d, _ := strconv.ParseFloat(msg.Args[1], 64)
|
2018-03-08 16:48:12 +03:00
|
|
|
time.Sleep(time.Duration(float64(time.Second) * d))
|
2018-10-29 01:49:45 +03:00
|
|
|
return OKMessage(msg, start), nil
|
2017-09-30 18:11:10 +03:00
|
|
|
}
|