Intro
Package 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/).
The main different to other sets is, every value of set is associated with a score, that is used in order to take the sorted set ordered, from the smallest to the greatest score.
The sorted set has O(log(N))
time complexity when doing Add(ZADD) and Remove(ZREM) operations and O(1)
time complexity when doing Contains operations.
Package zset is a go implmentation of https://github.com/redis/redis/blob/unstable/src/t_zset.c
Comparison
| Redis command | Go function |
|-----------------------|---------------------|
| ZADD | Add |
| ZINCRBY | IncrBy |
| ZREM | Remove |
| ZREMRANGEBYSCORE | RemoveRangeByScore |
| ZREMRANGEBYRANK | RemoveRangeByRank |
| ZUNION | Union |
| ZINTER | Inter |
| ZINTERCARD | TODO |
| ZDIFF | TODO |
| ZRANGE | Range |
| ZRANGEBYSCORE | IncrBy |
| ZREVRANGEBYSCORE | RevRangeByScore |
| ZCOUNT | Count |
| ZREVRANGE | RevRange |
| ZCARD | Len |
| ZSCORE | Score |
| ZRANK | Rank |
| ZREVRANK | RevRank |
| ZPOPMIN | TODO |
| ZPOPMAX | TODO |
| ZRANDMEMBER | TODO |
List of redis commands are generated from the following command:
cat redis/src/server.c | grep -o '"z.*",z.*Command' | grep -o '".*"' | cut -d '"' -f2
You may find that not all redis commands have corresponding go implementations,
the reason is as follows:
Unsupported Commands
Redis' zset can operates elements in lexicographic order, which is not commonly
used function, so zset does not support commands like ZREMRANGEBYLEX, ZLEXCOUNT
and so on.
| Redis command |
|-----------------------|
| ZREMRANGEBYLEX |
| ZRANGEBYLEX |
| ZREVRANGEBYLEX |
| ZLEXCOUNT |
In redis, user accesses zset via a string key. We do not need such string key
because we have variable. so the following commands are not implemented:
| Redis command |
|-----------------------|
| ZUNIONSTORE |
| ZINTERSTORE |
| ZDIFFSTORE |
| ZRANGESTORE |
| ZMSCORE |
| ZSCAN |
Tests
Unittests
coverage: 94.0% of statements
Benchmark
go test -v -cpuprofile cpu.pprof -cpu=1 -run=NOTEST -bench=. -benchmem -benchtime=100000x -count=10 -timeout=60m > y.txt && benchstat y.txt
name time/op
Contains100Hits/sortedset 39.5ns ± 1%
Contains50Hits/sortedset 43.4ns ± 4%
ContainsNoHits/sortedset 21.9ns ± 5%
Add/sortedset 53.6ns ± 1%
1Add99Contains/sortedset 38.1ns ±12%
10Add90Contains/sortedset 47.6ns ± 5%
50Add50Contains/sortedset 56.9ns ± 3%
1Add3Incr6Remove90Contains/sortedset 49.3ns ±11%
name alloc/op
Contains100Hits/sortedset 0.00B
Contains50Hits/sortedset 0.00B
ContainsNoHits/sortedset 0.00B
Add/sortedset 2.00B ± 0%
1Add99Contains/sortedset 0.00B
10Add90Contains/sortedset 0.00B
50Add50Contains/sortedset 1.00B ± 0%
1Add3Incr6Remove90Contains/sortedset 0.50B ±100%
name allocs/op
Contains100Hits/sortedset 0.00
Contains50Hits/sortedset 0.00
ContainsNoHits/sortedset 0.00
Add/sortedset 0.00
1Add99Contains/sortedset 0.00
10Add90Contains/sortedset 0.00
50Add50Contains/sortedset 0.00
1Add3Incr6Remove90Contains/sortedset 0.00
TODOs
- [x] implementation
- [x] godoc
- [x] unittest
- [x] benchmark
- [x] reamde