From b011af56b06f88d62728cb47aad39cdf136c0e1b Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Thu, 16 Nov 2023 09:35:27 +0300 Subject: [PATCH] Fixed - RScoredSortedSet.pollFirstEntries(count) and pollLastEntries(count) methods return wrong result --- .../org/redisson/RedissonScoredSortedSet.java | 37 ++++++++++++++++++- .../redisson/RedissonScoredSortedSetTest.java | 13 +++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/redisson/src/main/java/org/redisson/RedissonScoredSortedSet.java b/redisson/src/main/java/org/redisson/RedissonScoredSortedSet.java index 9d9a90f9d..0a8d392ea 100644 --- a/redisson/src/main/java/org/redisson/RedissonScoredSortedSet.java +++ b/redisson/src/main/java/org/redisson/RedissonScoredSortedSet.java @@ -132,6 +132,18 @@ public class RedissonScoredSortedSet extends RedissonExpirable implements RSc Collections.singletonList(name), from, to); } + private RFuture pollEntries(int from, int to, RedisCommand command) { + return commandExecutor.evalWriteAsync(getRawName(), codec, command, + "local v = redis.call('zrange', KEYS[1], ARGV[1], ARGV[2], 'WITHSCORES'); " + + "if #v > 0 then " + + "redis.call('zremrangebyrank', KEYS[1], ARGV[1], ARGV[2]); " + + "return v; " + + "end " + + "return v;", + Collections.singletonList(name), from, to); + } + + @Override public ScoredEntry pollFirstEntry() { return get(pollFirstEntryAsync()); @@ -168,7 +180,7 @@ public class RedissonScoredSortedSet extends RedissonExpirable implements RSc return new CompletableFutureWrapper<>(Collections.emptyList()); } - return poll(0, count-1, RedisCommands.EVAL_LIST_ENTRY); + return pollEntries(0, count-1, RedisCommands.EVAL_LIST_ENTRY); } @Override @@ -176,7 +188,7 @@ public class RedissonScoredSortedSet extends RedissonExpirable implements RSc if (count <= 0) { return new CompletableFutureWrapper<>(Collections.emptyList()); } - return poll(-count, -1, RedisCommands.EVAL_LIST_ENTRY); + return pollEntries(-count, -1, RedisCommands.EVAL_LIST_ENTRY); } private RFuture pollEntry(int from, int to, RedisCommand command) { @@ -569,6 +581,9 @@ public class RedissonScoredSortedSet extends RedissonExpirable implements RSc @Override public RFuture> firstEntryAsync() { + if (getServiceManager().isResp3()) { + return commandExecutor.readAsync(getRawName(), codec, RedisCommands.ZRANGE_SINGLE_ENTRY_V2, getRawName(), 0, 0, "WITHSCORES"); + } return commandExecutor.readAsync(getRawName(), codec, RedisCommands.ZRANGE_SINGLE_ENTRY, getRawName(), 0, 0, "WITHSCORES"); } @@ -589,6 +604,9 @@ public class RedissonScoredSortedSet extends RedissonExpirable implements RSc @Override public RFuture> lastEntryAsync() { + if (getServiceManager().isResp3()) { + return commandExecutor.readAsync(getRawName(), codec, RedisCommands.ZRANGE_SINGLE_ENTRY_V2, getRawName(), -1, -1, "WITHSCORES"); + } return commandExecutor.readAsync(getRawName(), codec, RedisCommands.ZRANGE_SINGLE_ENTRY, getRawName(), -1, -1, "WITHSCORES"); } @@ -1198,6 +1216,9 @@ public class RedissonScoredSortedSet extends RedissonExpirable implements RSc @Override public RFuture>> entryRangeAsync(int startIndex, int endIndex) { + if (getServiceManager().isResp3()) { + return commandExecutor.readAsync(getRawName(), codec, RedisCommands.ZRANGE_ENTRY_V2, getRawName(), startIndex, endIndex, "WITHSCORES"); + } return commandExecutor.readAsync(getRawName(), codec, RedisCommands.ZRANGE_ENTRY, getRawName(), startIndex, endIndex, "WITHSCORES"); } @@ -1208,6 +1229,9 @@ public class RedissonScoredSortedSet extends RedissonExpirable implements RSc @Override public RFuture>> entryRangeReversedAsync(int startIndex, int endIndex) { + if (getServiceManager().isResp3()) { + return commandExecutor.readAsync(getRawName(), codec, RedisCommands.ZREVRANGE_ENTRY_V2, getRawName(), startIndex, endIndex, "WITHSCORES"); + } return commandExecutor.readAsync(getRawName(), codec, RedisCommands.ZREVRANGE_ENTRY, getRawName(), startIndex, endIndex, "WITHSCORES"); } @@ -1288,6 +1312,9 @@ public class RedissonScoredSortedSet extends RedissonExpirable implements RSc public RFuture>> entryRangeAsync(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive, int offset, int count) { String startValue = value(startScore, startScoreInclusive); String endValue = value(endScore, endScoreInclusive); + if (getServiceManager().isResp3()) { + return commandExecutor.readAsync(getRawName(), codec, RedisCommands.ZRANGEBYSCORE_ENTRY_V2, getRawName(), startValue, endValue, "WITHSCORES", "LIMIT", offset, count); + } return commandExecutor.readAsync(getRawName(), codec, RedisCommands.ZRANGEBYSCORE_ENTRY, getRawName(), startValue, endValue, "WITHSCORES", "LIMIT", offset, count); } @@ -1302,6 +1329,9 @@ public class RedissonScoredSortedSet extends RedissonExpirable implements RSc double endScore, boolean endScoreInclusive) { String startValue = value(startScore, startScoreInclusive); String endValue = value(endScore, endScoreInclusive); + if (getServiceManager().isResp3()) { + return commandExecutor.readAsync(getRawName(), codec, RedisCommands.ZREVRANGEBYSCORE_ENTRY_V2, getRawName(), endValue, startValue, "WITHSCORES"); + } return commandExecutor.readAsync(getRawName(), codec, RedisCommands.ZREVRANGEBYSCORE_ENTRY, getRawName(), endValue, startValue, "WITHSCORES"); } @@ -1309,6 +1339,9 @@ public class RedissonScoredSortedSet extends RedissonExpirable implements RSc public RFuture>> entryRangeReversedAsync(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive, int offset, int count) { String startValue = value(startScore, startScoreInclusive); String endValue = value(endScore, endScoreInclusive); + if (getServiceManager().isResp3()) { + return commandExecutor.readAsync(getRawName(), codec, RedisCommands.ZREVRANGEBYSCORE_ENTRY_V2, getRawName(), endValue, startValue, "WITHSCORES", "LIMIT", offset, count); + } return commandExecutor.readAsync(getRawName(), codec, RedisCommands.ZREVRANGEBYSCORE_ENTRY, getRawName(), endValue, startValue, "WITHSCORES", "LIMIT", offset, count); } diff --git a/redisson/src/test/java/org/redisson/RedissonScoredSortedSetTest.java b/redisson/src/test/java/org/redisson/RedissonScoredSortedSetTest.java index f9b2dd6a0..265f589eb 100644 --- a/redisson/src/test/java/org/redisson/RedissonScoredSortedSetTest.java +++ b/redisson/src/test/java/org/redisson/RedissonScoredSortedSetTest.java @@ -891,6 +891,19 @@ public class RedissonScoredSortedSetTest extends RedisDockerTest { assertThat(set).containsExactly("b", "c"); } + @Test + public void testPollFirstEntries() { + RScoredSortedSet set = redisson.getScoredSortedSet("simple"); + Assertions.assertNull(set.pollFirst()); + + set.add(0.1, "a"); + set.add(0.2, "b"); + set.add(0.3, "c"); + + List> r = set.pollFirstEntries(2); + assertThat(r).containsExactlyInAnyOrder(new ScoredEntry<>(0.1, "a"), new ScoredEntry<>(0.2, "b")); + } + @Test public void testFirstLast() { RScoredSortedSet set = redisson.getScoredSortedSet("simple");