func (client *Client) CfInfo(key string) (map[string]int64, error) {
	conn := client.Pool.Get()
	defer conn.Close()
	return ParseInfoReply(redis.Values(conn.Do("CF.INFO", key)))
}
Return information about key
package redis_bloom_go
import (
	"errors"
	"fmt"
	"github.com/gomodule/redigo/redis"
	"strconv"
	"strings"
)
var maxConns = 500
type Client struct {
	Pool ConnPool
	Name string
}
type TDigestInfo struct {
	compression       int64
	capacity          int64
	mergedNodes       int64
	unmergedNodes     int64
	mergedWeight      float64
	unmergedWeight    float64
	totalCompressions int64
}
func (info *TDigestInfo) Compression() int64 {
	return info.compression
}
func (info *TDigestInfo) Capacity() int64 {
	return info.capacity
}
func (info *TDigestInfo) MergedNodes() int64 {
	return info.mergedNodes
}
func (info *TDigestInfo) UnmergedNodes() int64 {
	return info.unmergedNodes
}
func (info *TDigestInfo) MergedWeight() float64 {
	return info.mergedWeight
}
func (info *TDigestInfo) UnmergedWeight() float64 {
	return info.unmergedWeight
}
func (info *TDigestInfo) TotalCompressions() int64 {
	return info.totalCompressions
}
func NewClient(addr, name string, authPass *string) *Client {
	addrs := strings.Split(addr, ",")
	var pool ConnPool
	if len(addrs) == 1 {
		pool = NewSingleHostPool(addrs[0], authPass)
	} else {
		pool = NewMultiHostPool(addrs, authPass)
	}
	ret := &Client{
		Pool: pool,
		Name: name,
	}
	return ret
}
func NewClientFromPool(pool *redis.Pool, name string) *Client {
	ret := &Client{
		Pool: pool,
		Name: name,
	}
	return ret
}
func (client *Client) Reserve(key string, error_rate float64, capacity uint64) (err error) {
	conn := client.Pool.Get()
	defer conn.Close()
	_, err = conn.Do("BF.RESERVE", key, strconv.FormatFloat(error_rate, 'g', 16, 64), capacity)
	return err
}
func (client *Client) Add(key string, item string) (exists bool, err error) {
	conn := client.Pool.Get()
	defer conn.Close()
	return redis.Bool(conn.Do("BF.ADD", key, item))
}
func (client *Client) Exists(key string, item string) (exists bool, err error) {
	conn := client.Pool.Get()
	defer conn.Close()
	return redis.Bool(conn.Do("BF.EXISTS", key, item))
}
func (client *Client) Info(key string) (info map[string]int64, err error) {
	conn := client.Pool.Get()
	defer conn.Close()
	result, err := conn.Do("BF.INFO", key)
	if err != nil {
		return nil, err
	}
	values, err := redis.Values(result, nil)
	if err != nil {
		return nil, err
	}
	if len(values)%2 != 0 {
		return nil, errors.New("Info expects even number of values result")
	}
	info = map[string]int64{}
	for i := 0; i < len(values); i += 2 {
		key, err = redis.String(values[i], nil)
		if err != nil {
			return nil, err
		}
		info[key], err = redis.Int64(values[i+1], nil)
		if err != nil {
			return nil, err
		}
	}
	return info, nil
}
func (client *Client) BfAddMulti(key string, items []string) ([]int64, error) {
	conn := client.Pool.Get()
	defer conn.Close()
	args := redis.Args{key}.AddFlat(items)
	result, err := conn.Do("BF.MADD", args...)
	return redis.Int64s(result, err)
}
func (client *Client) BfExistsMulti(key string, items []string) ([]int64, error) {
	conn := client.Pool.Get()
	defer conn.Close()
	args := redis.Args{key}.AddFlat(items)
	result, err := conn.Do("BF.MEXISTS", args...)
	return redis.Int64s(result, err)
}
func (client *Client) BfScanDump(key string, iter int64) (int64, []byte, error) {
	conn := client.Pool.Get()
	defer conn.Close()
	reply, err := redis.Values(conn.Do("BF.SCANDUMP", key, iter))
	if err != nil || len(reply) != 2 {
		return 0, nil, err
	}
	iter = reply[0].(int64)
	if reply[1] == nil {
		return iter, nil, err
	}
	return iter, reply[1].([]byte), err
}
func (client *Client) BfLoadChunk(key string, iter int64, data []byte) (string, error) {
	conn := client.Pool.Get()
	defer conn.Close()
	return redis.String(conn.Do("BF.LOADCHUNK", key, iter, data))
}
func (client *Client) BfInsert(key string, cap int64, errorRatio float64, expansion int64, noCreate bool, nonScaling bool, items []string) (res []int64, err error) {
	conn := client.Pool.Get()
	defer conn.Close()
	args := redis.Args{key}
	if cap > 0 {
		args = args.Add("CAPACITY", cap)
	}
	if errorRatio > 0 {
		args = args.Add("ERROR", errorRatio)
	}
	if expansion > 0 {
		args = args.Add("EXPANSION", expansion)
	}
	if noCreate {
		args = args.Add("NOCREATE")
	}
	if nonScaling {
		args = args.Add("NONSCALING")
	}
	args = args.Add("ITEMS").AddFlat(items)
	var resp []interface{}
	var innerRes int64
	resp, err = redis.Values(conn.Do("BF.INSERT", args...))
	if err != nil {
		return
	}
	for _, arrayPos := range resp {
		innerRes, err = redis.Int64(arrayPos, err)
		if err == nil {
			res = append(res, innerRes)
		} else {
			break
		}
	}
	return
}
func (client *Client) TopkReserve(key string, topk int64, width int64, depth int64, decay float64) (string, error) {
	conn := client.Pool.Get()
	defer conn.Close()
	result, err := conn.Do("TOPK.RESERVE", key, topk, width, depth, strconv.FormatFloat(decay, 'g', 16, 64))
	return redis.String(result, err)
}
func (client *Client) TopkAdd(key string, items []string) ([]string, error) {
	conn := client.Pool.Get()
	defer conn.Close()
	args := redis.Args{key}.AddFlat(items)
	result, err := conn.Do("TOPK.ADD", args...)
	return redis.Strings(result, err)
}
func (client *Client) TopkCount(key string, items []string) (result []int64, err error) {
	conn := client.Pool.Get()
	defer conn.Close()
	args := redis.Args{key}.AddFlat(items)
	result, err = redis.Int64s(conn.Do("TOPK.COUNT", args...))
	return
}
func (client *Client) TopkQuery(key string, items []string) ([]int64, error) {
	conn := client.Pool.Get()
	defer conn.Close()
	args := redis.Args{key}.AddFlat(items)
	result, err := conn.Do("TOPK.QUERY", args...)
	return redis.Int64s(result, err)
}
func (client *Client) TopkListWithCount(key string) (map[string]int64, error) {
	conn := client.Pool.Get()
	defer conn.Close()
	return ParseInfoReply(redis.Values(conn.Do("TOPK.LIST", key, "WITHCOUNT")))
}
func (client *Client) TopkList(key string) ([]string, error) {
	conn := client.Pool.Get()
	defer conn.Close()
	result, err := conn.Do("TOPK.LIST", key)
	return redis.Strings(result, err)
}
func (client *Client) TopkInfo(key string) (map[string]string, error) {
	conn := client.Pool.Get()
	defer conn.Close()
	reply, err := conn.Do("TOPK.INFO", key)
	values, err := redis.Values(reply, err)
	if err != nil {
		return nil, err
	}
	if len(values)%2 != 0 {
		return nil, errors.New("expects even number of values result")
	}
	m := make(map[string]string, len(values)/2)
	for i := 0; i < len(values); i += 2 {
		k := values[i].(string)
		switch v := values[i+1].(type) {
		case []byte:
			m[k] = string(values[i+1].([]byte))
			break
		case int64:
			m[k] = strconv.FormatInt(values[i+1].(int64), 10)
		default:
			return nil, fmt.Errorf("unexpected element type for (Ints,String), got type %T", v)
		}
	}
	return m, err
}
func (client *Client) TopkIncrBy(key string, itemIncrements map[string]int64) ([]string, error) {
	conn := client.Pool.Get()
	defer conn.Close()
	args := redis.Args{key}
	for k, v := range itemIncrements {
		args = args.Add(k, v)
	}
	reply, err := conn.Do("TOPK.INCRBY", args...)
	return redis.Strings(reply, err)
}
func (client *Client) CmsInitByDim(key string, width int64, depth int64) (string, error) {
	conn := client.Pool.Get()
	defer conn.Close()
	result, err := conn.Do("CMS.INITBYDIM", key, width, depth)
	return redis.String(result, err)
}
func (client *Client) CmsInitByProb(key string, error float64, probability float64) (string, error) {
	conn := client.Pool.Get()
	defer conn.Close()
	result, err := conn.Do("CMS.INITBYPROB", key, error, probability)
	return redis.String(result, err)
}
func (client *Client) CmsIncrBy(key string, itemIncrements map[string]int64) ([]int64, error) {
	conn := client.Pool.Get()
	defer conn.Close()
	args := redis.Args{key}
	for k, v := range itemIncrements {
		args = args.Add(k, v)
	}
	result, err := conn.Do("CMS.INCRBY", args...)
	return redis.Int64s(result, err)
}
func (client *Client) CmsQuery(key string, items []string) ([]int64, error) {
	conn := client.Pool.Get()
	defer conn.Close()
	args := redis.Args{key}.AddFlat(items)
	result, err := conn.Do("CMS.QUERY", args...)
	return redis.Int64s(result, err)
}
func (client *Client) CmsMerge(dest string, srcs []string, weights []int64) (string, error) {
	conn := client.Pool.Get()
	defer conn.Close()
	args := redis.Args{dest}.Add(len(srcs)).AddFlat(srcs)
	if weights != nil && len(weights) > 0 {
		args = args.Add("WEIGHTS").AddFlat(weights)
	}
	return redis.String(conn.Do("CMS.MERGE", args...))
}
func (client *Client) CmsInfo(key string) (map[string]int64, error) {
	conn := client.Pool.Get()
	defer conn.Close()
	return ParseInfoReply(redis.Values(conn.Do("CMS.INFO", key)))
}
func (client *Client) CfReserve(key string, capacity int64, bucketSize int64, maxIterations int64, expansion int64) (string, error) {
	conn := client.Pool.Get()
	defer conn.Close()
	args := redis.Args{key}.Add(capacity)
	if bucketSize > 0 {
		args = args.Add("BUCKETSIZE", bucketSize)
	}
	if maxIterations > 0 {
		args = args.Add("MAXITERATIONS", maxIterations)
	}
	if expansion > 0 {
		args = args.Add("EXPANSION", expansion)
	}
	return redis.String(conn.Do("CF.RESERVE", args...))
}
func (client *Client) CfAdd(key string, item string) (bool, error) {
	conn := client.Pool.Get()
	defer conn.Close()
	return redis.Bool(conn.Do("CF.ADD", key, item))
}
func (client *Client) CfAddNx(key string, item string) (bool, error) {
	conn := client.Pool.Get()
	defer conn.Close()
	return redis.Bool(conn.Do("CF.ADDNX", key, item))
}
func (client *Client) CfInsert(key string, cap int64, noCreate bool, items []string) ([]int64, error) {
	conn := client.Pool.Get()
	defer conn.Close()
	args := GetInsertArgs(key, cap, noCreate, items)
	return redis.Int64s(conn.Do("CF.INSERT", args...))
}
func (client *Client) CfInsertNx(key string, cap int64, noCreate bool, items []string) ([]int64, error) {
	conn := client.Pool.Get()
	defer conn.Close()
	args := GetInsertArgs(key, cap, noCreate, items)
	return redis.Int64s(conn.Do("CF.INSERTNX", args...))
}
func GetInsertArgs(key string, cap int64, noCreate bool, items []string) redis.Args {
	args := redis.Args{key}
	if cap > 0 {
		args = args.Add("CAPACITY", cap)
	}
	if noCreate {
		args = args.Add("NOCREATE")
	}
	args = args.Add("ITEMS").AddFlat(items)
	return args
}
func (client *Client) CfExists(key string, item string) (bool, error) {
	conn := client.Pool.Get()
	defer conn.Close()
	return redis.Bool(conn.Do("CF.EXISTS", key, item))
}
func (client *Client) CfDel(key string, item string) (bool, error) {
	conn := client.Pool.Get()
	defer conn.Close()
	return redis.Bool(conn.Do("CF.DEL", key, item))
}
func (client *Client) CfCount(key string, item string) (int64, error) {
	conn := client.Pool.Get()
	defer conn.Close()
	return redis.Int64(conn.Do("CF.COUNT", key, item))
}
func (client *Client) CfScanDump(key string, iter int64) (int64, []byte, error) {
	conn := client.Pool.Get()
	defer conn.Close()
	reply, err := redis.Values(conn.Do("CF.SCANDUMP", key, iter))
	if err != nil || len(reply) != 2 {
		return 0, nil, err
	}
	iter = reply[0].(int64)
	if reply[1] == nil {
		return iter, nil, err
	}
	return iter, reply[1].([]byte), err
}
func (client *Client) CfLoadChunk(key string, iter int64, data []byte) (string, error) {
	conn := client.Pool.Get()
	defer conn.Close()
	return redis.String(conn.Do("CF.LOADCHUNK", key, iter, data))
}