forked from mirror/redis
Merge pull request #1909 from go-redis/feature/slice-helpers
feat: add Cmd.{String,Int,Float,Bool}Slice helpers and an example
This commit is contained in:
commit
cc09f96b8f
|
@ -24,3 +24,4 @@ linters:
|
|||
- errorlint
|
||||
- cyclop
|
||||
- forcetypeassert
|
||||
- forbidigo
|
||||
|
|
138
command.go
138
command.go
|
@ -216,7 +216,11 @@ func (cmd *Cmd) Text() (string, error) {
|
|||
if cmd.err != nil {
|
||||
return "", cmd.err
|
||||
}
|
||||
switch val := cmd.val.(type) {
|
||||
return toString(cmd.val)
|
||||
}
|
||||
|
||||
func toString(val interface{}) (string, error) {
|
||||
switch val := val.(type) {
|
||||
case string:
|
||||
return val, nil
|
||||
default:
|
||||
|
@ -244,7 +248,11 @@ func (cmd *Cmd) Int64() (int64, error) {
|
|||
if cmd.err != nil {
|
||||
return 0, cmd.err
|
||||
}
|
||||
switch val := cmd.val.(type) {
|
||||
return toInt64(cmd.val)
|
||||
}
|
||||
|
||||
func toInt64(val interface{}) (int64, error) {
|
||||
switch val := val.(type) {
|
||||
case int64:
|
||||
return val, nil
|
||||
case string:
|
||||
|
@ -259,7 +267,11 @@ func (cmd *Cmd) Uint64() (uint64, error) {
|
|||
if cmd.err != nil {
|
||||
return 0, cmd.err
|
||||
}
|
||||
switch val := cmd.val.(type) {
|
||||
return toUint64(cmd.val)
|
||||
}
|
||||
|
||||
func toUint64(val interface{}) (uint64, error) {
|
||||
switch val := val.(type) {
|
||||
case int64:
|
||||
return uint64(val), nil
|
||||
case string:
|
||||
|
@ -274,7 +286,11 @@ func (cmd *Cmd) Float32() (float32, error) {
|
|||
if cmd.err != nil {
|
||||
return 0, cmd.err
|
||||
}
|
||||
switch val := cmd.val.(type) {
|
||||
return toFloat32(cmd.val)
|
||||
}
|
||||
|
||||
func toFloat32(val interface{}) (float32, error) {
|
||||
switch val := val.(type) {
|
||||
case int64:
|
||||
return float32(val), nil
|
||||
case string:
|
||||
|
@ -293,7 +309,11 @@ func (cmd *Cmd) Float64() (float64, error) {
|
|||
if cmd.err != nil {
|
||||
return 0, cmd.err
|
||||
}
|
||||
switch val := cmd.val.(type) {
|
||||
return toFloat64(cmd.val)
|
||||
}
|
||||
|
||||
func toFloat64(val interface{}) (float64, error) {
|
||||
switch val := val.(type) {
|
||||
case int64:
|
||||
return float64(val), nil
|
||||
case string:
|
||||
|
@ -308,7 +328,11 @@ func (cmd *Cmd) Bool() (bool, error) {
|
|||
if cmd.err != nil {
|
||||
return false, cmd.err
|
||||
}
|
||||
switch val := cmd.val.(type) {
|
||||
return toBool(cmd.val)
|
||||
}
|
||||
|
||||
func toBool(val interface{}) (bool, error) {
|
||||
switch val := val.(type) {
|
||||
case int64:
|
||||
return val != 0, nil
|
||||
case string:
|
||||
|
@ -331,6 +355,108 @@ func (cmd *Cmd) Slice() ([]interface{}, error) {
|
|||
}
|
||||
}
|
||||
|
||||
func (cmd *Cmd) StringSlice() ([]string, error) {
|
||||
slice, err := cmd.Slice()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ss := make([]string, len(slice))
|
||||
for i, iface := range slice {
|
||||
val, err := toString(iface)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ss[i] = val
|
||||
}
|
||||
return ss, nil
|
||||
}
|
||||
|
||||
func (cmd *Cmd) Int64Slice() ([]int64, error) {
|
||||
slice, err := cmd.Slice()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nums := make([]int64, len(slice))
|
||||
for i, iface := range slice {
|
||||
val, err := toInt64(iface)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nums[i] = val
|
||||
}
|
||||
return nums, nil
|
||||
}
|
||||
|
||||
func (cmd *Cmd) Uint64Slice() ([]uint64, error) {
|
||||
slice, err := cmd.Slice()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nums := make([]uint64, len(slice))
|
||||
for i, iface := range slice {
|
||||
val, err := toUint64(iface)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nums[i] = val
|
||||
}
|
||||
return nums, nil
|
||||
}
|
||||
|
||||
func (cmd *Cmd) Float32Slice() ([]float32, error) {
|
||||
slice, err := cmd.Slice()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
floats := make([]float32, len(slice))
|
||||
for i, iface := range slice {
|
||||
val, err := toFloat32(iface)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
floats[i] = val
|
||||
}
|
||||
return floats, nil
|
||||
}
|
||||
|
||||
func (cmd *Cmd) Float64Slice() ([]float64, error) {
|
||||
slice, err := cmd.Slice()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
floats := make([]float64, len(slice))
|
||||
for i, iface := range slice {
|
||||
val, err := toFloat64(iface)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
floats[i] = val
|
||||
}
|
||||
return floats, nil
|
||||
}
|
||||
|
||||
func (cmd *Cmd) BoolSlice() ([]bool, error) {
|
||||
slice, err := cmd.Slice()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bools := make([]bool, len(slice))
|
||||
for i, iface := range slice {
|
||||
val, err := toBool(iface)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bools[i] = val
|
||||
}
|
||||
return bools, nil
|
||||
}
|
||||
|
||||
func (cmd *Cmd) readReply(rd *proto.Reader) (err error) {
|
||||
cmd.val, err = rd.ReadReply(sliceParser)
|
||||
return err
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
# RedisBloom example for go-redis
|
||||
|
||||
This is an example for
|
||||
[Bloom, Cuckoo, Count-Min, Top-K](https://redis.uptrace.dev/guide/bloom-cuckoo-count-min-top-k.html)
|
||||
article.
|
||||
|
||||
To run it, you need to compile and install
|
||||
[RedisBloom](https://oss.redis.com/redisbloom/Quick_Start/#building) module:
|
||||
|
||||
```shell
|
||||
go run .
|
||||
```
|
|
@ -0,0 +1,7 @@
|
|||
module github.com/go-redis/redis/example/redis-bloom
|
||||
|
||||
go 1.14
|
||||
|
||||
replace github.com/go-redis/redis/v8 => ../..
|
||||
|
||||
require github.com/go-redis/redis/v8 v8.11.3
|
|
@ -0,0 +1,100 @@
|
|||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
|
||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c=
|
||||
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
|
@ -0,0 +1,155 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/go-redis/redis/v8"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
|
||||
rdb := redis.NewClient(&redis.Options{
|
||||
Addr: ":6379",
|
||||
})
|
||||
_ = rdb.FlushDB(ctx).Err()
|
||||
|
||||
fmt.Printf("# BLOOM\n")
|
||||
bloomFilter(ctx, rdb)
|
||||
|
||||
fmt.Printf("\n# CUCKOO\n")
|
||||
cuckooFilter(ctx, rdb)
|
||||
|
||||
fmt.Printf("\n# COUNT-MIN\n")
|
||||
countMinSketch(ctx, rdb)
|
||||
|
||||
fmt.Printf("\n# TOP-K\n")
|
||||
topK(ctx, rdb)
|
||||
}
|
||||
|
||||
func bloomFilter(ctx context.Context, rdb *redis.Client) {
|
||||
inserted, err := rdb.Do(ctx, "BF.ADD", "bf_key", "item0").Bool()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if inserted {
|
||||
fmt.Println("item0 was inserted")
|
||||
} else {
|
||||
fmt.Println("item0 already exists")
|
||||
}
|
||||
|
||||
for _, item := range []string{"item0", "item1"} {
|
||||
exists, err := rdb.Do(ctx, "BF.EXISTS", "bf_key", item).Bool()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if exists {
|
||||
fmt.Printf("%s does exist\n", item)
|
||||
} else {
|
||||
fmt.Printf("%s does not exist\n", item)
|
||||
}
|
||||
}
|
||||
|
||||
bools, err := rdb.Do(ctx, "BF.MADD", "bf_key", "item1", "item2", "item3").BoolSlice()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println("adding multiple items:", bools)
|
||||
}
|
||||
|
||||
func cuckooFilter(ctx context.Context, rdb *redis.Client) {
|
||||
inserted, err := rdb.Do(ctx, "CF.ADDNX", "cf_key", "item0").Bool()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if inserted {
|
||||
fmt.Println("item0 was inserted")
|
||||
} else {
|
||||
fmt.Println("item0 already exists")
|
||||
}
|
||||
|
||||
for _, item := range []string{"item0", "item1"} {
|
||||
exists, err := rdb.Do(ctx, "CF.EXISTS", "cf_key", item).Bool()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if exists {
|
||||
fmt.Printf("%s does exist\n", item)
|
||||
} else {
|
||||
fmt.Printf("%s does not exist\n", item)
|
||||
}
|
||||
}
|
||||
|
||||
deleted, err := rdb.Do(ctx, "CF.DEL", "cf_key", "item0").Bool()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if deleted {
|
||||
fmt.Println("item0 was deleted")
|
||||
}
|
||||
}
|
||||
|
||||
func countMinSketch(ctx context.Context, rdb *redis.Client) {
|
||||
if err := rdb.Do(ctx, "CMS.INITBYPROB", "count_min", 0.001, 0.01).Err(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
items := []string{"item1", "item2", "item3", "item4", "item5"}
|
||||
counts := make(map[string]int, len(items))
|
||||
|
||||
for i := 0; i < 10000; i++ {
|
||||
n := rand.Intn(len(items))
|
||||
item := items[n]
|
||||
|
||||
if err := rdb.Do(ctx, "CMS.INCRBY", "count_min", item, 1).Err(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
counts[item]++
|
||||
}
|
||||
|
||||
for item, count := range counts {
|
||||
ns, err := rdb.Do(ctx, "CMS.QUERY", "count_min", item).Int64Slice()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Printf("%s: count-min=%d actual=%d\n", item, ns[0], count)
|
||||
}
|
||||
}
|
||||
|
||||
func topK(ctx context.Context, rdb *redis.Client) {
|
||||
if err := rdb.Do(ctx, "TOPK.RESERVE", "top_items", 3).Err(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
counts := map[string]int{
|
||||
"item1": 1000,
|
||||
"item2": 2000,
|
||||
"item3": 3000,
|
||||
"item4": 4000,
|
||||
"item5": 5000,
|
||||
"item6": 6000,
|
||||
}
|
||||
|
||||
for item, count := range counts {
|
||||
for i := 0; i < count; i++ {
|
||||
if err := rdb.Do(ctx, "TOPK.INCRBY", "top_items", item, 1).Err(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
items, err := rdb.Do(ctx, "TOPK.LIST", "top_items").StringSlice()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, item := range items {
|
||||
ns, err := rdb.Do(ctx, "TOPK.COUNT", "top_items", item).Int64Slice()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Printf("%s: top-k=%d actual=%d\n", item, ns[0], counts[item])
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue