// Package diagram provide diagram data structure and operation package diagram import ( "context" 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, lockLeaseTime uint64, needRefresh bool) (*RedisZSet, error) { token, err := clientTokenFromContext(ctx) if err != nil { return nil, err } return &RedisZSet{ ctx: ctx, rwLocker: locker.InitRWLocker(key, token, lockLeaseTime, needRefresh), storageClient: GetRedisClientInstance(), }, nil } // ZADD define func of add redis zset by members func (rs *RedisZSet) ZADD(setKey string, score float64, member any) 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 } // ZREPLACE atomically removes all existing members and adds one new member. func (rs *RedisZSet) ZREPLACE(setKey string, score float64, member any) error { if err := rs.rwLocker.WLock(rs.ctx); 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.TxPipelined(rs.ctx, func(pipe redis.Pipeliner) error { pipe.Del(rs.ctx, setKey) pipe.ZAdd(rs.ctx, setKey, redis.Z{Score: score, Member: member}) return nil }) if err != nil { logger.Error(rs.ctx, "replace zset member failed", "set_key", setKey, "member", 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 }