func SelectBool(opt, def bool) bool {
	if opt == false {
		return def
	}
	return opt
}
SelectBool takes an option and a default value and returns the default value if
the option is equal to the zero value, and the option otherwise.
package util
import (
	"errors"
	"fmt"
	"math/rand"
	"net"
	"regexp"
	"strconv"
	"time"
)
var HostportPattern = regexp.MustCompile(`^(\d+.\d+.\d+.\d+):\d+$`)
func CaptureHost(hostport string) string {
	host, _, err := net.SplitHostPort(hostport)
	if err != nil {
		return ""
	}
	return host
}
func CheckHostnameIPMismatch(local string, hostsMap map[string][]string) ([]string, error) {
	var message string
	test := func(message string, filter func(string) bool) ([]string, error) {
		var mismatched []string
		for _, hostports := range hostsMap {
			for _, hostport := range hostports {
				if filter(hostport) {
					mismatched = append(mismatched, hostport)
				}
			}
		}
		if len(mismatched) > 0 {
			return mismatched, errors.New(message)
		}
		return nil, nil
	}
	if HostportPattern.MatchString(local) {
		message = "Your host identifier looks like an IP address and there are bootstrap " +
			"hosts that appear to be specified with hostnames. These inconsistencies may " +
			"lead to subtle node communication issues."
		return test(message, func(hostport string) bool {
			return !HostportPattern.MatchString(hostport)
		})
	}
	message = "Your host identifier looks like a hostname and there are bootstrap hosts " +
		"that appear to be specified with IP addresses. These inconsistencies may lead " +
		"to subtle node communication issues"
	return test(message, func(hostport string) bool {
		return HostportPattern.MatchString(hostport)
	})
}
func CheckLocalMissing(local string, hostports []string) error {
	if !StringInSlice(hostports, local) {
		return errors.New("local node missing from hosts")
	}
	return nil
}
func SingleNodeCluster(hostport string, hostMap map[string][]string) bool {
	if len(hostMap) > 1 {
		return false
	}
	host := CaptureHost(hostport)
	_, ok := hostMap[host]
	if !ok {
		return false
	}
	if len(hostMap[host]) > 1 {
		return false
	}
	if hostMap[host][0] == hostport {
		return true
	}
	return false
}
func HostPortsByHost(hostports []string) (hostMap map[string][]string) {
	hostMap = make(map[string][]string)
	for _, hostport := range hostports {
		host := CaptureHost(hostport)
		if host != "" {
			hostMap[host] = append(hostMap[host], hostport)
		}
	}
	return
}
func TimeZero() time.Time {
	return time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC)
}
func TimeNowMS() int64 {
	return UnixMS(time.Now())
}
func MS(d time.Duration) int64 {
	return d.Nanoseconds() / 1000000
}
func UnixMS(t time.Time) int64 {
	return t.UnixNano() / 1000000
}
func StringInSlice(slice []string, str string) bool {
	for _, b := range slice {
		if str == b {
			return true
		}
	}
	return false
}
func ShuffleStrings(strings []string) []string {
	newStrings := make([]string, len(strings))
	newIndexes := rand.Perm(len(strings))
	for o, n := range newIndexes {
		newStrings[n] = strings[o]
	}
	return newStrings
}
func ShuffleStringsInPlace(strings []string) {
	for i := range strings {
		j := rand.Intn(i + 1)
		strings[i], strings[j] = strings[j], strings[i]
	}
}
func TakeNode(nodes *[]string, index int) string {
	if len(*nodes) == 0 {
		return ""
	}
	var i int
	if index >= 0 {
		if index >= len(*nodes) {
			return ""
		}
		i = index
	} else {
		i = rand.Intn(len(*nodes))
	}
	node := (*nodes)[i]
	*nodes = append((*nodes)[:i], (*nodes)[i+1:]...)
	return node
}
func SelectInt(opt, def int) int {
	if opt == 0 {
		return def
	}
	return opt
}
func SelectFloat(opt, def float64) float64 {
	if opt == 0 {
		return def
	}
	return opt
}
func SelectDuration(opt, def time.Duration) time.Duration {
	if opt == time.Duration(0) {
		return def
	}
	return opt
}