mirror of
https://github.com/redis/go-redis.git
synced 2025-09-11 18:10:43 +03:00
Init
This commit is contained in:
12
example/redis-bloom/README.md
Normal file
12
example/redis-bloom/README.md
Normal file
@@ -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 .
|
||||
```
|
12
example/redis-bloom/go.mod
Normal file
12
example/redis-bloom/go.mod
Normal file
@@ -0,0 +1,12 @@
|
||||
module github.com/redis/go-redis/example/redis-bloom
|
||||
|
||||
go 1.18
|
||||
|
||||
replace github.com/redis/go-redis/v9 => ../..
|
||||
|
||||
require github.com/redis/go-redis/v9 v9.5.3
|
||||
|
||||
require (
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
)
|
6
example/redis-bloom/go.sum
Normal file
6
example/redis-bloom/go.sum
Normal file
@@ -0,0 +1,6 @@
|
||||
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
|
||||
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
|
||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
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=
|
155
example/redis-bloom/main.go
Normal file
155
example/redis-bloom/main.go
Normal file
@@ -0,0 +1,155 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
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])
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user