diff --git a/redisson/src/main/java/org/redisson/RedissonAtomicDouble.java b/redisson/src/main/java/org/redisson/RedissonAtomicDouble.java index 79468d914..531727fc3 100644 --- a/redisson/src/main/java/org/redisson/RedissonAtomicDouble.java +++ b/redisson/src/main/java/org/redisson/RedissonAtomicDouble.java @@ -170,7 +170,43 @@ public class RedissonAtomicDouble extends RedissonExpirable implements RAtomicDo public RFuture setAsync(double newValue) { return commandExecutor.writeAsync(getRawName(), StringCodec.INSTANCE, RedisCommands.SET, getRawName(), BigDecimal.valueOf(newValue).toPlainString()); } - + + @Override + public boolean setIfLess(double less, double value) { + return get(setIfLessAsync(less, value)); + } + + @Override + public RFuture setIfLessAsync(double less, double value) { + return commandExecutor.evalWriteAsync(getRawName(), StringCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN, + "local currValue = redis.call('get', KEYS[1]); " + + "currValue = currValue == false and 0 or tonumber(currValue);" + + "if currValue < tonumber(ARGV[1]) then " + + "redis.call('set', KEYS[1], ARGV[2]); " + + "return 1;" + + "end; " + + "return 0;", + Collections.singletonList(getRawName()), less, value); + } + + @Override + public boolean setIfGreater(double greater, double value) { + return get(setIfGreaterAsync(greater, value)); + } + + @Override + public RFuture setIfGreaterAsync(double greater, double value) { + return commandExecutor.evalWriteAsync(getRawName(), StringCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN, + "local currValue = redis.call('get', KEYS[1]); " + + "currValue = currValue == false and 0 or tonumber(currValue);" + + "if currValue > tonumber(ARGV[1]) then " + + "redis.call('set', KEYS[1], ARGV[2]); " + + "return 1;" + + "end; " + + "return 0;", + Collections.singletonList(getRawName()), greater, value); + } + public String toString() { return Double.toString(get()); } diff --git a/redisson/src/main/java/org/redisson/RedissonAtomicLong.java b/redisson/src/main/java/org/redisson/RedissonAtomicLong.java index 686b84cb1..491ae8510 100644 --- a/redisson/src/main/java/org/redisson/RedissonAtomicLong.java +++ b/redisson/src/main/java/org/redisson/RedissonAtomicLong.java @@ -168,7 +168,43 @@ public class RedissonAtomicLong extends RedissonExpirable implements RAtomicLong public RFuture setAsync(long newValue) { return commandExecutor.writeAsync(getRawName(), StringCodec.INSTANCE, RedisCommands.SET, getRawName(), newValue); } - + + @Override + public boolean setIfLess(long less, long value) { + return get(setIfLessAsync(less, value)); + } + + @Override + public RFuture setIfLessAsync(long less, long value) { + return commandExecutor.evalWriteAsync(getRawName(), StringCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN, + "local currValue = redis.call('get', KEYS[1]); " + + "currValue = currValue == false and 0 or tonumber(currValue);" + + "if currValue < tonumber(ARGV[1]) then " + + "redis.call('set', KEYS[1], ARGV[2]); " + + "return 1;" + + "end; " + + "return 0;", + Collections.singletonList(getRawName()), less, value); + } + + @Override + public boolean setIfGreater(long greater, long value) { + return get(setIfGreaterAsync(greater, value)); + } + + @Override + public RFuture setIfGreaterAsync(long greater, long value) { + return commandExecutor.evalWriteAsync(getRawName(), StringCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN, + "local currValue = redis.call('get', KEYS[1]); " + + "currValue = currValue == false and 0 or tonumber(currValue);" + + "if currValue > tonumber(ARGV[1]) then " + + "redis.call('set', KEYS[1], ARGV[2]); " + + "return 1;" + + "end; " + + "return 0;", + Collections.singletonList(getRawName()), greater, value); + } + public String toString() { return Long.toString(get()); } diff --git a/redisson/src/main/java/org/redisson/api/RAtomicDouble.java b/redisson/src/main/java/org/redisson/api/RAtomicDouble.java index 007c42f87..6fa13f312 100644 --- a/redisson/src/main/java/org/redisson/api/RAtomicDouble.java +++ b/redisson/src/main/java/org/redisson/api/RAtomicDouble.java @@ -106,6 +106,26 @@ public interface RAtomicDouble extends RExpirable, RAtomicDoubleAsync { * @param newValue the new value */ void set(double newValue); + + /** + * Atomically sets the given value if current value is less than + * the special value + * + * @param less compare value + * @param value newValue + * @return true when the value update is successful + */ + boolean setIfLess(double less, double value); + + /** + * Atomically sets the given value if current value is greater than + * the special value + * + * @param greater compare value + * @param value newValue + * @return true when the value update is successful + */ + boolean setIfGreater(double greater, double value); /** * Adds object event listener diff --git a/redisson/src/main/java/org/redisson/api/RAtomicDoubleAsync.java b/redisson/src/main/java/org/redisson/api/RAtomicDoubleAsync.java index f8ecf608f..4c1c6dff4 100644 --- a/redisson/src/main/java/org/redisson/api/RAtomicDoubleAsync.java +++ b/redisson/src/main/java/org/redisson/api/RAtomicDoubleAsync.java @@ -107,6 +107,26 @@ public interface RAtomicDoubleAsync extends RExpirableAsync { * @return void */ RFuture setAsync(double newValue); + + /** + * Atomically sets the given value if current value is less than + * the special value + * + * @param less compare value + * @param value newValue + * @return true when the value update is successful + */ + RFuture setIfLessAsync(double less, double value); + + /** + * Atomically sets the given value if current value is greater than + * the special value + * + * @param greater compare value + * @param value newValue + * @return true when the value update is successful + */ + RFuture setIfGreaterAsync(double greater, double value); /** * Adds object event listener diff --git a/redisson/src/main/java/org/redisson/api/RAtomicDoubleReactive.java b/redisson/src/main/java/org/redisson/api/RAtomicDoubleReactive.java index 2f3f9af8a..bfc906587 100644 --- a/redisson/src/main/java/org/redisson/api/RAtomicDoubleReactive.java +++ b/redisson/src/main/java/org/redisson/api/RAtomicDoubleReactive.java @@ -109,5 +109,25 @@ public interface RAtomicDoubleReactive extends RExpirableReactive { * @return void */ Mono set(double newValue); + + /** + * Atomically sets the given value if current value is less than + * the special value + * + * @param less compare value + * @param value newValue + * @return true when the value update is successful + */ + Mono setIfLess(double less, double value); + + /** + * Atomically sets the given value if current value is greater than + * the special value + * + * @param greater compare value + * @param value newValue + * @return true when the value update is successful + */ + Mono setIfGreater(double greater, double value); } diff --git a/redisson/src/main/java/org/redisson/api/RAtomicDoubleRx.java b/redisson/src/main/java/org/redisson/api/RAtomicDoubleRx.java index 61e9102fe..e7d960e69 100644 --- a/redisson/src/main/java/org/redisson/api/RAtomicDoubleRx.java +++ b/redisson/src/main/java/org/redisson/api/RAtomicDoubleRx.java @@ -110,5 +110,25 @@ public interface RAtomicDoubleRx extends RExpirableRx { * @return void */ Completable set(double newValue); + + /** + * Atomically sets the given value if current value is less than + * the special value + * + * @param less compare value + * @param value newValue + * @return true when the value update is successful + */ + Single setIfLess(double less, double value); + + /** + * Atomically sets the given value if current value is greater than + * the special value + * + * @param greater compare value + * @param value newValue + * @return true when the value update is successful + */ + Single setIfGreater(double greater, double value); } diff --git a/redisson/src/main/java/org/redisson/api/RAtomicLong.java b/redisson/src/main/java/org/redisson/api/RAtomicLong.java index ab83876c5..264f29376 100644 --- a/redisson/src/main/java/org/redisson/api/RAtomicLong.java +++ b/redisson/src/main/java/org/redisson/api/RAtomicLong.java @@ -106,6 +106,26 @@ public interface RAtomicLong extends RExpirable, RAtomicLongAsync { * @param newValue the new value */ void set(long newValue); + + /** + * Atomically sets the given value if current value is less than + * the special value + * + * @param less compare value + * @param value newValue + * @return true when the value update is successful + */ + boolean setIfLess(long less, long value); + + /** + * Atomically sets the given value if current value is greater than + * the special value + * + * @param greater compare value + * @param value newValue + * @return true when the value update is successful + */ + boolean setIfGreater(long greater, long value); /** * Adds object event listener diff --git a/redisson/src/main/java/org/redisson/api/RAtomicLongAsync.java b/redisson/src/main/java/org/redisson/api/RAtomicLongAsync.java index e81074003..bd955238d 100644 --- a/redisson/src/main/java/org/redisson/api/RAtomicLongAsync.java +++ b/redisson/src/main/java/org/redisson/api/RAtomicLongAsync.java @@ -107,6 +107,26 @@ public interface RAtomicLongAsync extends RExpirableAsync { * @return void */ RFuture setAsync(long newValue); + + /** + * Atomically sets the given value if current value is less than + * the special value + * + * @param less compare value + * @param value newValue + * @return true when the value update is successful + */ + RFuture setIfLessAsync(long less, long value); + + /** + * Atomically sets the given value if current value is greater than + * the special value + * + * @param greater compare value + * @param value newValue + * @return true when the value update is successful + */ + RFuture setIfGreaterAsync(long greater, long value); /** * Adds object event listener diff --git a/redisson/src/main/java/org/redisson/api/RAtomicLongReactive.java b/redisson/src/main/java/org/redisson/api/RAtomicLongReactive.java index dea2f88d0..8c7948ac9 100644 --- a/redisson/src/main/java/org/redisson/api/RAtomicLongReactive.java +++ b/redisson/src/main/java/org/redisson/api/RAtomicLongReactive.java @@ -109,5 +109,25 @@ public interface RAtomicLongReactive extends RExpirableReactive { * @return void */ Mono set(long newValue); + + /** + * Atomically sets the given value if current value is less than + * the special value + * + * @param less compare value + * @param value newValue + * @return true when the value update is successful + */ + Mono setIfLess(long less, long value); + + /** + * Atomically sets the given value if current value is greater than + * the special value + * + * @param greater compare value + * @param value newValue + * @return true when the value update is successful + */ + Mono setIfGreater(long greater, long value); } diff --git a/redisson/src/main/java/org/redisson/api/RAtomicLongRx.java b/redisson/src/main/java/org/redisson/api/RAtomicLongRx.java index aee44293e..abec6f88c 100644 --- a/redisson/src/main/java/org/redisson/api/RAtomicLongRx.java +++ b/redisson/src/main/java/org/redisson/api/RAtomicLongRx.java @@ -110,5 +110,25 @@ public interface RAtomicLongRx extends RExpirableRx { * @return void */ Completable set(long newValue); + + /** + * Atomically sets the given value if current value is less than + * the special value + * + * @param less compare value + * @param value newValue + * @return true when the value update is successful + */ + Single setIfLess(long less, long value); + + /** + * Atomically sets the given value if current value is greater than + * the special value + * + * @param greater compare value + * @param value newValue + * @return true when the value update is successful + */ + Single setIfGreater(long greater, long value); } diff --git a/redisson/src/test/java/org/redisson/RedissonAtomicDoubleTest.java b/redisson/src/test/java/org/redisson/RedissonAtomicDoubleTest.java index dd9c43baa..d9231214c 100644 --- a/redisson/src/test/java/org/redisson/RedissonAtomicDoubleTest.java +++ b/redisson/src/test/java/org/redisson/RedissonAtomicDoubleTest.java @@ -8,7 +8,29 @@ import java.math.BigDecimal; import static org.assertj.core.api.Assertions.assertThat; public class RedissonAtomicDoubleTest extends RedisDockerTest { - + + @Test + public void testSetIfLess() { + RAtomicDouble al = redisson.getAtomicDouble("test"); + assertThat(al.setIfLess(0, 1)).isFalse(); + assertThat(al.get()).isEqualTo(0); + + al.set(12); + assertThat(al.setIfLess(13, 1)).isTrue(); + assertThat(al.get()).isEqualTo(1); + } + + @Test + public void testSetIfGreater() { + RAtomicDouble al = redisson.getAtomicDouble("test"); + assertThat(al.setIfLess(0, 1)).isFalse(); + assertThat(al.get()).isEqualTo(0); + + al.set(12); + assertThat(al.setIfGreater(11, 1)).isTrue(); + assertThat(al.get()).isEqualTo(1); + } + @Test public void testGetAndSet() { RAtomicDouble al = redisson.getAtomicDouble("test"); diff --git a/redisson/src/test/java/org/redisson/RedissonAtomicLongReactiveTest.java b/redisson/src/test/java/org/redisson/RedissonAtomicLongReactiveTest.java index eeb0d1211..11e56b215 100644 --- a/redisson/src/test/java/org/redisson/RedissonAtomicLongReactiveTest.java +++ b/redisson/src/test/java/org/redisson/RedissonAtomicLongReactiveTest.java @@ -5,7 +5,29 @@ import org.junit.jupiter.api.Test; import org.redisson.api.RAtomicLongReactive; public class RedissonAtomicLongReactiveTest extends BaseReactiveTest { - + + @Test + public void testSetIfLess() { + RAtomicLongReactive al = redisson.getAtomicLong("test"); + Assertions.assertFalse(sync(al.setIfLess(0, 1))); + Assertions.assertEquals(sync(al.get()).longValue(), 0L); + + sync(al.set(12)); + Assertions.assertTrue(sync(al.setIfLess(13, 1))); + Assertions.assertEquals(sync(al.get()).longValue(), 1L); + } + + @Test + public void testSetIfGreater() { + RAtomicLongReactive al = redisson.getAtomicLong("test"); + Assertions.assertFalse(sync(al.setIfGreater(0, 1))); + Assertions.assertEquals(sync(al.get()).longValue(), 0L); + + sync(al.set(12)); + Assertions.assertTrue(sync(al.setIfGreater(11, 1))); + Assertions.assertEquals(sync(al.get()).longValue(), 1L); + } + @Test public void testCompareAndSet() { RAtomicLongReactive al = redisson.getAtomicLong("test"); diff --git a/redisson/src/test/java/org/redisson/RedissonAtomicLongTest.java b/redisson/src/test/java/org/redisson/RedissonAtomicLongTest.java index 16fabb8c0..5ae101746 100644 --- a/redisson/src/test/java/org/redisson/RedissonAtomicLongTest.java +++ b/redisson/src/test/java/org/redisson/RedissonAtomicLongTest.java @@ -7,7 +7,29 @@ import org.redisson.api.RAtomicLong; import static org.assertj.core.api.Assertions.assertThat; public class RedissonAtomicLongTest extends RedisDockerTest { - + + @Test + public void testSetIfLess() { + RAtomicLong al = redisson.getAtomicLong("test"); + assertThat(al.setIfLess(0, 1)).isFalse(); + assertThat(al.get()).isEqualTo(0); + + al.set(12); + assertThat(al.setIfLess(13, 1)).isTrue(); + assertThat(al.get()).isEqualTo(1); + } + + @Test + public void testSetIfGreater() { + RAtomicLong al = redisson.getAtomicLong("test"); + assertThat(al.setIfLess(0, 1)).isFalse(); + assertThat(al.get()).isEqualTo(0); + + al.set(12); + assertThat(al.setIfGreater(11, 1)).isTrue(); + assertThat(al.get()).isEqualTo(1); + } + @Test public void testGetAndSet() { RAtomicLong al = redisson.getAtomicLong("test");