diff --git a/src/main/java/org/redisson/RedissonSet.java b/src/main/java/org/redisson/RedissonSet.java index d5a2787b7..530663bf8 100644 --- a/src/main/java/org/redisson/RedissonSet.java +++ b/src/main/java/org/redisson/RedissonSet.java @@ -144,6 +144,16 @@ public class RedissonSet extends RedissonExpirable implements RSet { return commandExecutor.writeAsync(getName(), codec, RedisCommands.SPOP_SINGLE, getName()); } + @Override + public V random() { + return get(randomAsync()); + } + + @Override + public Future randomAsync() { + return commandExecutor.writeAsync(getName(), codec, RedisCommands.SRANDMEMBER_SINGLE, getName()); + } + @Override public Future removeAsync(Object o) { return commandExecutor.writeAsync(getName(o), codec, RedisCommands.SREM_SINGLE, getName(o), o); diff --git a/src/main/java/org/redisson/RedissonSetMultimapValues.java b/src/main/java/org/redisson/RedissonSetMultimapValues.java index 89ede9133..d11e24d8c 100644 --- a/src/main/java/org/redisson/RedissonSetMultimapValues.java +++ b/src/main/java/org/redisson/RedissonSetMultimapValues.java @@ -194,6 +194,16 @@ public class RedissonSetMultimapValues extends RedissonExpirable implements R return commandExecutor.writeAsync(getName(), codec, RedisCommands.SPOP_SINGLE, getName()); } + @Override + public V random() { + return get(randomAsync()); + } + + @Override + public Future randomAsync() { + return commandExecutor.writeAsync(getName(), codec, RedisCommands.SRANDMEMBER_SINGLE, getName()); + } + @Override public Future removeAsync(Object o) { return commandExecutor.evalWriteAsync(getName(), codec, EVAL_CONTAINS_VALUE, diff --git a/src/main/java/org/redisson/api/RSetReactive.java b/src/main/java/org/redisson/api/RSetReactive.java index e5d1c6f53..c9e29f226 100644 --- a/src/main/java/org/redisson/api/RSetReactive.java +++ b/src/main/java/org/redisson/api/RSetReactive.java @@ -36,6 +36,14 @@ public interface RSetReactive extends RCollectionReactive { */ Publisher removeRandom(); + /** + * Returns random element from set + * in async mode + * + * @return + */ + Publisher random(); + /** * Move a member from this set to the given destination set in async mode. * diff --git a/src/main/java/org/redisson/client/protocol/RedisCommands.java b/src/main/java/org/redisson/client/protocol/RedisCommands.java index 210c18a0f..7eb1dd8f3 100644 --- a/src/main/java/org/redisson/client/protocol/RedisCommands.java +++ b/src/main/java/org/redisson/client/protocol/RedisCommands.java @@ -131,6 +131,7 @@ public interface RedisCommands { RedisCommand SREM_SINGLE = new RedisCommand("SREM", new BooleanAmountReplayConvertor(), 2, ValueType.OBJECTS); RedisCommand SMOVE = new RedisCommand("SMOVE", new BooleanReplayConvertor(), 3); RedisCommand> SMEMBERS = new RedisCommand>("SMEMBERS", new ObjectSetReplayDecoder()); + RedisCommand SRANDMEMBER_SINGLE = new RedisCommand("SRANDMEMBER"); RedisCommand> SSCAN = new RedisCommand>("SSCAN", new NestedMultiDecoder(new ObjectListReplayDecoder(), new ListScanResultReplayDecoder()), ValueType.OBJECT); RedisCommand> EVAL_SSCAN = new RedisCommand>("EVAL", new NestedMultiDecoder(new ObjectListReplayDecoder(), new ListScanResultReplayDecoder()), ValueType.OBJECT); RedisCommand> EVAL_ZSCAN = new RedisCommand>("EVAL", new NestedMultiDecoder(new ObjectListReplayDecoder(), new ListScanResultReplayDecoder()), ValueType.OBJECT); diff --git a/src/main/java/org/redisson/core/RSet.java b/src/main/java/org/redisson/core/RSet.java index 8b78d28be..cb9f41f2d 100644 --- a/src/main/java/org/redisson/core/RSet.java +++ b/src/main/java/org/redisson/core/RSet.java @@ -33,6 +33,13 @@ public interface RSet extends Set, RExpirable, RSetAsync { */ V removeRandom(); + /** + * Returns random element from set + * + * @return + */ + V random(); + /** * Move a member from this set to the given destination set in. * diff --git a/src/main/java/org/redisson/core/RSetAsync.java b/src/main/java/org/redisson/core/RSetAsync.java index 922f639b5..c545cad98 100644 --- a/src/main/java/org/redisson/core/RSetAsync.java +++ b/src/main/java/org/redisson/core/RSetAsync.java @@ -36,6 +36,14 @@ public interface RSetAsync extends RCollectionAsync { */ Future removeRandomAsync(); + /** + * Returns random element from set + * in async mode + * + * @return + */ + Future randomAsync(); + /** * Move a member from this set to the given destination set in async mode. * diff --git a/src/main/java/org/redisson/reactive/RedissonSetReactive.java b/src/main/java/org/redisson/reactive/RedissonSetReactive.java index 9f5fe1098..586b0a495 100644 --- a/src/main/java/org/redisson/reactive/RedissonSetReactive.java +++ b/src/main/java/org/redisson/reactive/RedissonSetReactive.java @@ -80,6 +80,11 @@ public class RedissonSetReactive extends RedissonExpirableReactive implements return reactive(instance.removeRandomAsync()); } + @Override + public Publisher random() { + return reactive(instance.randomAsync()); + } + @Override public Publisher remove(Object o) { return reactive(instance.removeAsync(o)); diff --git a/src/test/java/org/redisson/RedissonSetReactiveTest.java b/src/test/java/org/redisson/RedissonSetReactiveTest.java index 5a356cca9..9e4fdc43e 100644 --- a/src/test/java/org/redisson/RedissonSetReactiveTest.java +++ b/src/test/java/org/redisson/RedissonSetReactiveTest.java @@ -57,6 +57,19 @@ public class RedissonSetReactiveTest extends BaseReactiveTest { Assert.assertNull(sync(set.removeRandom())); } + @Test + public void testRandom() { + RSetReactive set = redisson.getSet("simple"); + sync(set.add(1)); + sync(set.add(2)); + sync(set.add(3)); + + MatcherAssert.assertThat(sync(set.random()), Matchers.isOneOf(1, 2, 3)); + MatcherAssert.assertThat(sync(set.random()), Matchers.isOneOf(1, 2, 3)); + MatcherAssert.assertThat(sync(set.random()), Matchers.isOneOf(1, 2, 3)); + Assert.assertThat(sync(set), Matchers.containsInAnyOrder(1, 2, 3)); + } + @Test public void testAddBean() throws InterruptedException, ExecutionException { SimpleBean sb = new SimpleBean(); diff --git a/src/test/java/org/redisson/RedissonSetTest.java b/src/test/java/org/redisson/RedissonSetTest.java index c16f319ee..b508e4840 100644 --- a/src/test/java/org/redisson/RedissonSetTest.java +++ b/src/test/java/org/redisson/RedissonSetTest.java @@ -46,6 +46,19 @@ public class RedissonSetTest extends BaseTest { assertThat(set.removeRandom()).isNull(); } + @Test + public void testRandom() { + RSet set = redisson.getSet("simple"); + set.add(1); + set.add(2); + set.add(3); + + assertThat(set.random()).isIn(1, 2, 3); + assertThat(set.random()).isIn(1, 2, 3); + assertThat(set.random()).isIn(1, 2, 3); + assertThat(set).containsOnly(1, 2, 3); + } + @Test public void testAddBean() throws InterruptedException, ExecutionException { SimpleBean sb = new SimpleBean();