func main() {
	var buf bytes.Buffer
	logger = log.New(&buf, "", log.LstdFlags|log.Lshortfile)
	logger.SetOutput(os.Stdout)

	// use all cpus in the system for concurrency
	runtime.GOMAXPROCS(runtime.NumCPU())
	readFlags()

	if *debugMode {
		Logger.SetLogger(logger)
		Logger.SetLevel(DEBUG)
	}

	// launch profiler if in profile mode
	if *profileMode {
		go func() {
			logger.Println(http.ListenAndServe(":6060", nil))
		}()
	}

	printBenchmarkParams()

	clientPolicy := NewClientPolicy()
	// cache lots  connections
	clientPolicy.ConnectionQueueSize = *connQueueSize
	clientPolicy.User = *user
	clientPolicy.Password = *password
	clientPolicy.Timeout = 10 * time.Second
	client, err := NewClientWithPolicy(clientPolicy, *host, *port)
	if err != nil {
		logger.Fatal(err)
	}

	logger.Println("Nodes Found:", client.GetNodeNames())

	go reporter()
	wg.Add(*concurrency)
	for i := 1; i < *concurrency; i++ {
		go runBench(client, i-1, *keyCount / *concurrency)
	}
	go runBench(client, *concurrency-1, *keyCount / *concurrency + *keyCount%*concurrency)

	wg.Wait()

	// send term to reporter, and wait for it to terminate
	countReportChan <- &TStats{Exit: true}
	time.Sleep(10 * time.Millisecond)
	<-countReportChan
}
func parseLatency(param string) (int, int) {
	re := regexp.MustCompile(`(\d+)[:,](\d+)`)
	values := re.FindStringSubmatch(param)

	// see if the value is supplied
	if len(values) > 2 && strings.Trim(values[1], " ") != "" && strings.Trim(values[2], " ") != "" {
		if value1, err := strconv.Atoi(strings.Trim(values[1], " ")); err == nil {
			if value2, err := strconv.Atoi(strings.Trim(values[2], " ")); err == nil {
				return value1, value2
			}
		}
	}

	logger.Fatal("Wrong latency values requested.")
	return 0, 0
}