From 729046db88f6e4bec3ab1cb81d35859dd15f5cc0 Mon Sep 17 00:00:00 2001 From: Nikita Date: Wed, 23 Dec 2015 14:53:23 +0300 Subject: [PATCH] RMapCache.fastPut with TTL added --- .../java/org/redisson/RedissonMapCache.java | 26 +++++++++++++++++++ .../client/protocol/RedisCommand.java | 7 +++++ .../java/org/redisson/core/RMapCache.java | 2 ++ .../org/redisson/core/RMapCacheAsync.java | 2 ++ .../org/redisson/RedissonMapCacheTest.java | 9 +++++++ 5 files changed, 46 insertions(+) diff --git a/src/main/java/org/redisson/RedissonMapCache.java b/src/main/java/org/redisson/RedissonMapCache.java index 19e1e674d..c924dea4d 100644 --- a/src/main/java/org/redisson/RedissonMapCache.java +++ b/src/main/java/org/redisson/RedissonMapCache.java @@ -71,6 +71,7 @@ public class RedissonMapCache extends RedissonMap implements RMapCac private static final RedisCommand EVAL_REMOVE = new RedisCommand("EVAL", 4, ValueType.MAP_KEY, ValueType.MAP_VALUE); private static final RedisCommand EVAL_REMOVE_VALUE = new RedisCommand("EVAL", new LongReplayConvertor(), 5, ValueType.MAP); private static final RedisCommand EVAL_PUT_TTL = new RedisCommand("EVAL", 6, ValueType.MAP, ValueType.MAP_VALUE); + private static final RedisCommand EVAL_FAST_PUT_TTL = new RedisCommand("EVAL", new BooleanReplayConvertor(), 6, ValueType.MAP, ValueType.MAP_VALUE); private static final RedisCommand> EVAL_GET_TTL = new RedisCommand>("EVAL", new TTLMapValueReplayDecoder(), 5, ValueType.MAP_KEY, ValueType.MAP_VALUE); private static final RedisCommand> EVAL_CONTAINS_KEY = new RedisCommand>("EVAL", new ObjectListReplayDecoder(), 5, ValueType.MAP_KEY); private static final RedisCommand> EVAL_CONTAINS_VALUE = new RedisCommand>("EVAL", new ObjectListReplayDecoder(), 5, ValueType.MAP_VALUE); @@ -279,6 +280,31 @@ public class RedissonMapCache extends RedissonMap implements RMapCac return get(putAsync(key, value, ttl, unit)); } + @Override + public boolean fastPut(K key, V value, long ttl, TimeUnit unit) { + return get(fastPutAsync(key, value, ttl, unit)); + } + + @Override + public Future fastPutAsync(K key, V value, long ttl, TimeUnit unit) { + if (ttl < 0) { + throw new IllegalArgumentException("TTL can't be negative"); + } + if (ttl == 0) { + return fastPutAsync(key, value); + } + + if (unit == null) { + throw new NullPointerException("TimeUnit param can't be null"); + } + + long timeoutDate = System.currentTimeMillis() + unit.toMillis(ttl); + return commandExecutor.evalWriteAsync(getName(), codec, EVAL_FAST_PUT_TTL, + "redis.call('zadd', KEYS[2], ARGV[1], ARGV[2]); " + + "return redis.call('hset', KEYS[1], ARGV[2], ARGV[3]); ", + Arrays.asList(getName(), getTimeoutSetName()), timeoutDate, key, value); + } + @Override public Future putAsync(K key, V value, long ttl, TimeUnit unit) { if (ttl < 0) { diff --git a/src/main/java/org/redisson/client/protocol/RedisCommand.java b/src/main/java/org/redisson/client/protocol/RedisCommand.java index f48ede62e..5111dbbb6 100644 --- a/src/main/java/org/redisson/client/protocol/RedisCommand.java +++ b/src/main/java/org/redisson/client/protocol/RedisCommand.java @@ -91,6 +91,13 @@ public class RedisCommand { this(name, null, null, null, inParamIndex); } + public RedisCommand(String name, Convertor convertor, int inParamIndex, ValueType inParamType, ValueType outParamType) { + this(name, null, null, null, inParamIndex); + this.convertor = convertor; + this.inParamType = Arrays.asList(inParamType); + this.outParamType = outParamType; + } + public RedisCommand(String name, int inParamIndex, ValueType inParamType, ValueType outParamType) { this(name, null, null, null, inParamIndex); this.inParamType = Arrays.asList(inParamType); diff --git a/src/main/java/org/redisson/core/RMapCache.java b/src/main/java/org/redisson/core/RMapCache.java index 659cb14a2..7c0e59c21 100644 --- a/src/main/java/org/redisson/core/RMapCache.java +++ b/src/main/java/org/redisson/core/RMapCache.java @@ -71,6 +71,8 @@ public interface RMapCache extends RMap, RMapCacheAsync { */ V put(K key, V value, long ttl, TimeUnit unit); + boolean fastPut(K key, V value, long ttl, TimeUnit unit); + /** * Returns the number of entries in cache. * This number can reflects expired entries too diff --git a/src/main/java/org/redisson/core/RMapCacheAsync.java b/src/main/java/org/redisson/core/RMapCacheAsync.java index 108e2ddb0..64a4bfbd6 100644 --- a/src/main/java/org/redisson/core/RMapCacheAsync.java +++ b/src/main/java/org/redisson/core/RMapCacheAsync.java @@ -73,6 +73,8 @@ public interface RMapCacheAsync extends RMapAsync { */ Future putAsync(K key, V value, long ttl, TimeUnit unit); + Future fastPutAsync(K key, V value, long ttl, TimeUnit unit); + /** * Returns the number of entries in cache. * This number can reflects expired entries too diff --git a/src/test/java/org/redisson/RedissonMapCacheTest.java b/src/test/java/org/redisson/RedissonMapCacheTest.java index 2d0d019d6..23c363cbb 100644 --- a/src/test/java/org/redisson/RedissonMapCacheTest.java +++ b/src/test/java/org/redisson/RedissonMapCacheTest.java @@ -25,6 +25,7 @@ import org.redisson.core.RMapCache; import org.redisson.core.RSetCache; import org.redisson.core.RMap; +import io.netty.util.Timeout; import io.netty.util.concurrent.Future; public class RedissonMapCacheTest extends BaseTest { @@ -596,6 +597,14 @@ public class RedissonMapCacheTest extends BaseTest { Assert.assertEquals(1, map.size()); } + @Test + public void testFastPutWithTTL() throws Exception { + RMapCache map = redisson.getMapCache("simple"); + Assert.assertTrue(map.fastPut(1, 2, 2, TimeUnit.SECONDS)); + Assert.assertFalse(map.fastPut(1, 2, 2, TimeUnit.SECONDS)); + Assert.assertEquals(1, map.size()); + } + @Test public void testEquals() { RMapCache map = redisson.getMapCache("simple");