From de6ec8bec3fa77c2a8f748c2281c23b4d3a4176f Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Wed, 31 May 2023 15:01:34 +0300 Subject: [PATCH] Feature - firstEntry() and lastEntry() methods added to RScoredSortedSet object. #5074 --- .../org/redisson/RedissonScoredSortedSet.java | 22 ++++++++++++++++++- .../org/redisson/api/RScoredSortedSet.java | 14 ++++++++++++ .../redisson/api/RScoredSortedSetAsync.java | 14 ++++++++++++ .../api/RScoredSortedSetReactive.java | 14 ++++++++++++ .../org/redisson/api/RScoredSortedSetRx.java | 14 ++++++++++++ .../client/protocol/RedisCommands.java | 1 + .../redisson/RedissonScoredSortedSetTest.java | 13 +++++++++++ 7 files changed, 91 insertions(+), 1 deletion(-) diff --git a/redisson/src/main/java/org/redisson/RedissonScoredSortedSet.java b/redisson/src/main/java/org/redisson/RedissonScoredSortedSet.java index 7fc6a60c0..b554c2d14 100644 --- a/redisson/src/main/java/org/redisson/RedissonScoredSortedSet.java +++ b/redisson/src/main/java/org/redisson/RedissonScoredSortedSet.java @@ -557,6 +557,16 @@ public class RedissonScoredSortedSet extends RedissonExpirable implements RSc return commandExecutor.readAsync(getRawName(), codec, RedisCommands.ZRANGE_SINGLE, getRawName(), 0, 0); } + @Override + public ScoredEntry firstEntry() { + return get(firstEntryAsync()); + } + + @Override + public RFuture> firstEntryAsync() { + return commandExecutor.readAsync(getRawName(), codec, RedisCommands.ZRANGE_SINGLE_ENTRY, getRawName(), 0, 0, "WITHSCORES"); + } + @Override public V last() { return get(lastAsync()); @@ -566,7 +576,17 @@ public class RedissonScoredSortedSet extends RedissonExpirable implements RSc public RFuture lastAsync() { return commandExecutor.readAsync(getRawName(), codec, RedisCommands.ZRANGE_SINGLE, getRawName(), -1, -1); } - + + @Override + public ScoredEntry lastEntry() { + return get(lastEntryAsync()); + } + + @Override + public RFuture> lastEntryAsync() { + return commandExecutor.readAsync(getRawName(), codec, RedisCommands.ZRANGE_SINGLE_ENTRY, getRawName(), -1, -1, "WITHSCORES"); + } + @Override public Double firstScore() { return get(firstScoreAsync()); diff --git a/redisson/src/main/java/org/redisson/api/RScoredSortedSet.java b/redisson/src/main/java/org/redisson/api/RScoredSortedSet.java index 1f6bcf31d..be5668670 100644 --- a/redisson/src/main/java/org/redisson/api/RScoredSortedSet.java +++ b/redisson/src/main/java/org/redisson/api/RScoredSortedSet.java @@ -364,6 +364,13 @@ public interface RScoredSortedSet extends RScoredSortedSetAsync, Iterable< */ V first(); + /** + * Returns the head entry (value and its score) or {@code null} if this sorted set is empty. + * + * @return the head entry or {@code null} if this sorted set is empty + */ + ScoredEntry firstEntry(); + /** * Returns the tail element or {@code null} if this sorted set is empty. * @@ -371,6 +378,13 @@ public interface RScoredSortedSet extends RScoredSortedSetAsync, Iterable< */ V last(); + /** + * Returns the tail entry (value and its score) or {@code null} if this sorted set is empty. + * + * @return the tail entry or {@code null} if this sorted set is empty + */ + ScoredEntry lastEntry(); + /** * Returns score of the tail element or returns {@code null} if this sorted set is empty. * diff --git a/redisson/src/main/java/org/redisson/api/RScoredSortedSetAsync.java b/redisson/src/main/java/org/redisson/api/RScoredSortedSetAsync.java index 96fefbe43..e8156f86f 100644 --- a/redisson/src/main/java/org/redisson/api/RScoredSortedSetAsync.java +++ b/redisson/src/main/java/org/redisson/api/RScoredSortedSetAsync.java @@ -325,6 +325,13 @@ public interface RScoredSortedSetAsync extends RExpirableAsync, RSortableAsyn */ RFuture firstAsync(); + /** + * Returns the head entry (value and its score) or {@code null} if this sorted set is empty. + * + * @return the head entry or {@code null} if this sorted set is empty + */ + RFuture> firstEntryAsync(); + /** * Returns the tail element or {@code null} if this sorted set is empty. * @@ -332,6 +339,13 @@ public interface RScoredSortedSetAsync extends RExpirableAsync, RSortableAsyn */ RFuture lastAsync(); + /** + * Returns the tail entry (value and its score) or {@code null} if this sorted set is empty. + * + * @return the tail entry or {@code null} if this sorted set is empty + */ + RFuture> lastEntryAsync(); + /** * Returns score of the head element or returns {@code null} if this sorted set is empty. * diff --git a/redisson/src/main/java/org/redisson/api/RScoredSortedSetReactive.java b/redisson/src/main/java/org/redisson/api/RScoredSortedSetReactive.java index 14ebb5c6c..5363dacb9 100644 --- a/redisson/src/main/java/org/redisson/api/RScoredSortedSetReactive.java +++ b/redisson/src/main/java/org/redisson/api/RScoredSortedSetReactive.java @@ -314,6 +314,13 @@ public interface RScoredSortedSetReactive extends RExpirableReactive, RSortab */ Mono first(); + /** + * Returns the head entry (value and its score) or {@code null} if this sorted set is empty. + * + * @return the head entry or {@code null} if this sorted set is empty + */ + Mono> firstEntry(); + /** * Returns the tail element or {@code null} if this sorted set is empty. * @@ -321,6 +328,13 @@ public interface RScoredSortedSetReactive extends RExpirableReactive, RSortab */ Mono last(); + /** + * Returns the tail entry (value and its score) or {@code null} if this sorted set is empty. + * + * @return the tail entry or {@code null} if this sorted set is empty + */ + Mono> lastEntry(); + /** * Returns score of the head element or returns {@code null} if this sorted set is empty. * diff --git a/redisson/src/main/java/org/redisson/api/RScoredSortedSetRx.java b/redisson/src/main/java/org/redisson/api/RScoredSortedSetRx.java index 105def573..22f7f40f2 100644 --- a/redisson/src/main/java/org/redisson/api/RScoredSortedSetRx.java +++ b/redisson/src/main/java/org/redisson/api/RScoredSortedSetRx.java @@ -315,6 +315,13 @@ public interface RScoredSortedSetRx extends RExpirableRx, RSortableRx> */ Maybe first(); + /** + * Returns the head entry (value and its score) or {@code null} if this sorted set is empty. + * + * @return the head entry or {@code null} if this sorted set is empty + */ + Maybe> firstEntry(); + /** * Returns the tail element or {@code null} if this sorted set is empty. * @@ -322,6 +329,13 @@ public interface RScoredSortedSetRx extends RExpirableRx, RSortableRx> */ Maybe last(); + /** + * Returns the tail entry (value and its score) or {@code null} if this sorted set is empty. + * + * @return the tail entry or {@code null} if this sorted set is empty + */ + Maybe> lastEntry(); + /** * Returns score of the head element or returns {@code null} if this sorted set is empty. * diff --git a/redisson/src/main/java/org/redisson/client/protocol/RedisCommands.java b/redisson/src/main/java/org/redisson/client/protocol/RedisCommands.java index 1f624bc31..fb80df8e4 100644 --- a/redisson/src/main/java/org/redisson/client/protocol/RedisCommands.java +++ b/redisson/src/main/java/org/redisson/client/protocol/RedisCommands.java @@ -111,6 +111,7 @@ public interface RedisCommands { RedisCommand ZREVRANK_INT = new RedisCommand("ZREVRANK", new IntegerReplayConvertor()); RedisCommand> ZREVRANK_ENTRY = new RedisCommand<>("ZREVRANK", new RankedEntryDecoder()); RedisCommand ZRANGE_SINGLE = new RedisCommand("ZRANGE", new ListFirstObjectDecoder()); + RedisCommand ZRANGE_SINGLE_ENTRY = new RedisCommand<>("ZRANGE", new ListFirstObjectDecoder(new ScoredSortedSetReplayDecoder())); RedisStrictCommand ZRANGE_SINGLE_SCORE = new RedisStrictCommand("ZRANGE", new ObjectFirstScoreReplayDecoder()); RedisCommand> ZRANGE = new RedisCommand>("ZRANGE", new ObjectListReplayDecoder()); RedisCommand ZRANGESTORE = new RedisCommand<>("ZRANGESTORE", new IntegerReplayConvertor()); diff --git a/redisson/src/test/java/org/redisson/RedissonScoredSortedSetTest.java b/redisson/src/test/java/org/redisson/RedissonScoredSortedSetTest.java index 0ddbbbdf3..b06dec69d 100644 --- a/redisson/src/test/java/org/redisson/RedissonScoredSortedSetTest.java +++ b/redisson/src/test/java/org/redisson/RedissonScoredSortedSetTest.java @@ -27,6 +27,19 @@ import static org.junit.jupiter.api.Assertions.assertTrue; public class RedissonScoredSortedSetTest extends BaseTest { + @Test + public void testEntries() { + RScoredSortedSet set = redisson.getScoredSortedSet("test"); + set.add(1.1, "v1"); + set.add(1.2, "v2"); + set.add(1.3, "v3"); + + ScoredEntry s = set.firstEntry(); + assertThat(s).isEqualTo(new ScoredEntry<>(1.1, "v1")); + ScoredEntry s2 = set.lastEntry(); + assertThat(s2).isEqualTo(new ScoredEntry<>(1.3, "v3")); + } + @Test public void testPollEntryDuration() { RScoredSortedSet set = redisson.getScoredSortedSet("test");