124 lines
3.0 KiB
Go
124 lines
3.0 KiB
Go
// Package diagram provide diagram data structure and operation
|
|
package diagram
|
|
|
|
import (
|
|
"context"
|
|
"iter"
|
|
"maps"
|
|
|
|
locker "modelRT/distributedlock"
|
|
"modelRT/logger"
|
|
|
|
"github.com/redis/go-redis/v9"
|
|
)
|
|
|
|
// RedisZSet defines the encapsulation struct of redis zset type
|
|
type RedisZSet struct {
|
|
ctx context.Context
|
|
rwLocker *locker.RedissionRWLocker
|
|
storageClient *redis.Client
|
|
}
|
|
|
|
// NewRedisZSet define func of new redis zset instance
|
|
func NewRedisZSet(ctx context.Context, key string, token string, lockLeaseTime uint64, needRefresh bool) *RedisZSet {
|
|
return &RedisZSet{
|
|
ctx: ctx,
|
|
rwLocker: locker.InitRWLocker(key, token, lockLeaseTime, needRefresh),
|
|
storageClient: GetRedisClientInstance(),
|
|
}
|
|
}
|
|
|
|
// ZADD define func of add redis zset by members
|
|
func (rs *RedisZSet) ZADD(setKey string, score float64, member interface{}) error {
|
|
err := rs.rwLocker.WLock(rs.ctx)
|
|
if err != nil {
|
|
logger.Error(rs.ctx, "lock wLock by setKey failed", "set_key", setKey, "error", err)
|
|
return err
|
|
}
|
|
defer rs.rwLocker.UnWLock(rs.ctx)
|
|
|
|
err = rs.storageClient.ZAdd(rs.ctx, setKey, redis.Z{Score: score, Member: member}).Err()
|
|
if err != nil {
|
|
logger.Error(rs.ctx, "add set by score and memebers failed", "set_key", setKey, "members", member, "error", err)
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ZRANGE define func of returns the specified range of elements in the sorted set stored by key
|
|
func (rs *RedisZSet) ZRANGE(setKey string, start, stop int64) ([]string, error) {
|
|
var results []string
|
|
|
|
err := rs.rwLocker.RLock(rs.ctx)
|
|
if err != nil {
|
|
logger.Error(rs.ctx, "lock RLock by setKey failed", "set_key", setKey, "error", err)
|
|
return nil, err
|
|
}
|
|
|
|
defer func() {
|
|
err = rs.rwLocker.UnRLock(rs.ctx)
|
|
if err != nil {
|
|
logger.Error(rs.ctx, "unlock RLock by setKey failed", "set_key", setKey, "error", err)
|
|
}
|
|
}()
|
|
|
|
results, err = rs.storageClient.ZRange(rs.ctx, setKey, start, stop).Result()
|
|
if err != nil {
|
|
logger.Error(rs.ctx, "range set by key failed", "set_key", setKey, "start", start, "stop", stop, "error", err)
|
|
return nil, err
|
|
}
|
|
return results, nil
|
|
}
|
|
|
|
type Comparer[T any] interface {
|
|
Compare(T) int
|
|
}
|
|
|
|
type ComparableComparer[T any] interface {
|
|
Compare(T) int
|
|
comparable // 直接嵌入 comparable 约束
|
|
}
|
|
|
|
type methodNode[E Comparer[E]] struct {
|
|
value E
|
|
left *methodNode[E]
|
|
right *methodNode[E]
|
|
}
|
|
|
|
type MethodTree[E Comparer[E]] struct {
|
|
root *methodNode[E]
|
|
}
|
|
|
|
type OrderedSet[E interface {
|
|
comparable
|
|
Comparer[E]
|
|
}] struct {
|
|
tree MethodTree[E]
|
|
elements map[E]bool
|
|
}
|
|
|
|
type ComparableOrderedSet[E ComparableComparer[E]] struct {
|
|
tree MethodTree[E]
|
|
elements map[E]bool
|
|
}
|
|
|
|
type Set[E any] interface {
|
|
Insert(E)
|
|
Delete(E)
|
|
Has(E) bool
|
|
All() iter.Seq[E]
|
|
}
|
|
|
|
func InsertAll[E any](set Set[E], seq iter.Seq[E]) {
|
|
for v := range seq {
|
|
set.Insert(v)
|
|
}
|
|
}
|
|
|
|
type HashSet[E comparable] map[E]bool
|
|
|
|
func (s HashSet[E]) Insert(v E) { s[v] = true }
|
|
func (s HashSet[E]) Delete(v E) { delete(s, v) }
|
|
func (s HashSet[E]) Has(v E) bool { return s[v] }
|
|
func (s HashSet[E]) All() iter.Seq[E] { return maps.Keys(s) }
|