github.com/bytedance/gopkg@v0.0.0-20240514070511-01b2cbcf35e1/collection/zset/readme.md (about)

     1  # zset
     2  
     3  [![Go Reference](https://pkg.go.dev/badge/github.com/bytedance/gopkg/collection/zset.svg)](https://pkg.go.dev/github.com/bytedance/gopkg/collection/zset)
     4  
     5  ## Introduction
     6  
     7  zset provides a concurrent-safety sorted set, can be used as a local replacement of [Redis' zset](https://redis.com/ebook/part-2-core-concepts/chapter-3-commands-in-redis/3-5-sorted-sets/).
     8  
     9  The main difference to other sets is, every value of set is associated with a score, that is used to take the sorted set ordered, from the smallest to the greatest score.
    10  
    11  The zset has `O(log(N))` time complexity when doing Add(ZADD) and Remove(ZREM) operations and `O(1)` time complexity when doing Contains operations.
    12  
    13  ## Features
    14  
    15  - Concurrent safe API
    16  - Values are sorted with score
    17  - Implementation equivalent to redis 
    18  - Fast skiplist level randomization
    19  
    20  ## Comparison
    21  
    22  | Redis command         | Go function         |
    23  |-----------------------|---------------------|
    24  | ZADD                  | Add                 |
    25  | ZINCRBY               | IncrBy              |
    26  | ZREM                  | Remove              |
    27  | ZREMRANGEBYSCORE      | RemoveRangeByScore  |
    28  | ZREMRANGEBYRANK       | RemoveRangeByRank   |
    29  | ZUNION                | Union               |
    30  | ZINTER                | Inter               |
    31  | ZINTERCARD            | *TODO*              |
    32  | ZDIFF                 | *TODO*              |
    33  | ZRANGE                | Range               |
    34  | ZRANGEBYSCORE         | IncrBy              |
    35  | ZREVRANGEBYSCORE      | RevRangeByScore     |
    36  | ZCOUNT                | Count               |
    37  | ZREVRANGE             | RevRange            |
    38  | ZCARD                 | Len                 |
    39  | ZSCORE                | Score               |
    40  | ZRANK                 | Rank                |
    41  | ZREVRANK              | RevRank             |
    42  | ZPOPMIN               | *TODO*              |
    43  | ZPOPMAX               | *TODO*              |
    44  | ZRANDMEMBER           | *TODO*              |
    45  
    46  List of redis commands are generated from the following command:
    47  
    48  ```bash
    49  cat redis/src/server.c | grep -o '"z.*",z.*Command' | grep -o '".*"' | cut -d '"' -f2
    50  ```
    51  
    52  You may find that not all redis commands have corresponding go implementations,
    53  the reason is as follows:
    54  
    55  ### Unsupported Commands
    56  
    57  Redis' zset can operates elements in lexicographic order, which is not commonly
    58  used function, so zset does not support commands like ZREMRANGEBYLEX, ZLEXCOUNT
    59  and so on.
    60  
    61  | Redis command         |
    62  |-----------------------|
    63  | ZREMRANGEBYLEX        |
    64  | ZRANGEBYLEX           |
    65  | ZREVRANGEBYLEX        |
    66  | ZLEXCOUNT             |
    67  
    68  In redis, user accesses zset via a string key. We do not need such string key
    69  because we have variable. so the following commands are not implemented:
    70  
    71  | Redis command         |
    72  |-----------------------|
    73  | ZUNIONSTORE           |
    74  | ZINTERSTORE           |
    75  | ZDIFFSTORE            |
    76  | ZRANGESTORE           |
    77  | ZMSCORE               |
    78  | ZSCAN                 |
    79  
    80  ## QuickStart
    81  
    82  ```go
    83  package main
    84  
    85  import (
    86  	"fmt"
    87  
    88  	"github.com/bytedance/gopkg/collection/zset"
    89  )
    90  
    91  func main() {
    92  	z := zset.NewFloat64()
    93  
    94  	values := []string{"Alice", "Bob", "Zhang"}
    95  	scores := []float64{90, 89, 59.9}
    96  	for i := range values {
    97  		z.Add(scores[i], values[i])
    98  	}
    99  
   100  	s, ok := z.Score("Alice")
   101  	if ok {
   102  		fmt.Println("Alice's score is", s)
   103  	}
   104  
   105  	n := z.Count(0, 60)
   106  	fmt.Println("There are", n, "people below 60 points")
   107  
   108  	for _, n := range z.Range(0, -1) {
   109  		fmt.Println("zset range found", n.Value, n.Score)
   110  	}
   111  }
   112  ```