using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using StackExchange.Redis; using WIDESEAWCS_RedisService.Connection; using WIDESEAWCS_RedisService.Options; namespace WIDESEAWCS_RedisService.Leaderboard { public class RedisLeaderboardService : ILeaderboardService { private readonly IRedisConnectionManager _connectionManager; private readonly RedisOptions _options; private readonly ILogger _logger; public RedisLeaderboardService( IRedisConnectionManager connectionManager, IOptions options, ILogger logger) { _connectionManager = connectionManager; _options = options.Value; _logger = logger; } private string BuildKey(string key) => $"{_options.KeyPrefix}board:{key}"; public bool AddOrUpdate(string boardName, string member, double score) { return _connectionManager.GetDatabase().SortedSetAdd(BuildKey(boardName), member, score); } public double IncrementScore(string boardName, string member, double increment) { return _connectionManager.GetDatabase().SortedSetIncrement(BuildKey(boardName), member, increment); } public long? GetRank(string boardName, string member) { return _connectionManager.GetDatabase().SortedSetRank(BuildKey(boardName), member, Order.Descending); } public double? GetScore(string boardName, string member) { return _connectionManager.GetDatabase().SortedSetScore(BuildKey(boardName), member); } public List GetTopN(string boardName, int count) { return GetRange(boardName, 0, count - 1); } public List GetRange(string boardName, long start, long stop) { var entries = _connectionManager.GetDatabase() .SortedSetRangeByRankWithScores(BuildKey(boardName), start, stop, Order.Descending); return entries.Select((e, i) => new LeaderboardEntry { Member = e.Element.ToString(), Score = e.Score, Rank = start + i }).ToList(); } public bool Remove(string boardName, string member) { return _connectionManager.GetDatabase().SortedSetRemove(BuildKey(boardName), member); } public long GetCount(string boardName) { return _connectionManager.GetDatabase().SortedSetLength(BuildKey(boardName)); } } }