From 3a9b555a4d0c55ebca0015a3aa742aeb774bd29b Mon Sep 17 00:00:00 2001 From: Nikita Date: Thu, 16 Mar 2017 20:05:08 +0300 Subject: [PATCH] Fixed - NPE during RLocalCachedMap.fastRemove invocation #810 --- .../org/redisson/RedissonLocalCachedMap.java | 51 +++++++++++-------- .../redisson/RedissonLocalCachedMapTest.java | 11 ++++ 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/redisson/src/main/java/org/redisson/RedissonLocalCachedMap.java b/redisson/src/main/java/org/redisson/RedissonLocalCachedMap.java index a9c45fc07..79054717c 100644 --- a/redisson/src/main/java/org/redisson/RedissonLocalCachedMap.java +++ b/redisson/src/main/java/org/redisson/RedissonLocalCachedMap.java @@ -389,35 +389,42 @@ public class RedissonLocalCachedMap extends RedissonMap implements R throw new NullPointerException(); } - List params = new ArrayList(); - params.add(invalidateEntryOnChange); + if (invalidateEntryOnChange == 1) { + List params = new ArrayList(keys.length*2); + for (K k : keys) { + byte[] keyEncoded = encodeMapKey(k); + params.add(keyEncoded); + + CacheKey cacheKey = toCacheKey(keyEncoded); + cache.remove(cacheKey); + byte[] msgEncoded = encode(new LocalCachedMapInvalidate(instanceId, cacheKey.getKeyHash())); + params.add(msgEncoded); + } + + return commandExecutor.evalWriteAsync(getName(), codec, RedisCommands.EVAL_LONG, + "local counter = 0; " + + "for j = 1, #ARGV, 2 do " + + "if redis.call('hdel', KEYS[1], ARGV[j]) == 1 then " + + "redis.call('publish', KEYS[2], ARGV[j+1]); " + + "counter = counter + 1;" + + "end;" + + "end;" + + "return counter;", + Arrays.asList(getName(), invalidationTopic.getChannelNames().get(0)), + params.toArray()); + } + + List params = new ArrayList(keys.length + 1); + params.add(getName()); for (K k : keys) { byte[] keyEncoded = encodeMapKey(k); params.add(keyEncoded); CacheKey cacheKey = toCacheKey(keyEncoded); cache.remove(cacheKey); - if (invalidateEntryOnChange == 1) { - byte[] msgEncoded = encode(new LocalCachedMapInvalidate(instanceId, cacheKey.getKeyHash())); - params.add(msgEncoded); - } else { - params.add(null); - } } - - return commandExecutor.evalWriteAsync(getName(), codec, RedisCommands.EVAL_LONG, - "local counter = 0; " + - "for j = 2, #ARGV, 2 do " - + "if redis.call('hdel', KEYS[1], ARGV[j]) == 1 then " - + "if ARGV[1] == '1' then " - + "redis.call('publish', KEYS[2], ARGV[j+1]); " - + "end; " - + "counter = counter + 1;" - + "end;" - + "end;" - + "return counter;", - Arrays.asList(getName(), invalidationTopic.getChannelNames().get(0)), - params.toArray()); + + return commandExecutor.writeAsync(getName(), codec, RedisCommands.HDEL, params.toArray()); } diff --git a/redisson/src/test/java/org/redisson/RedissonLocalCachedMapTest.java b/redisson/src/test/java/org/redisson/RedissonLocalCachedMapTest.java index 9cbd71abe..67ecee903 100644 --- a/redisson/src/test/java/org/redisson/RedissonLocalCachedMapTest.java +++ b/redisson/src/test/java/org/redisson/RedissonLocalCachedMapTest.java @@ -570,6 +570,17 @@ public class RedissonLocalCachedMapTest extends BaseTest { assertThat(map.fastRemove(2)).isEqualTo(0); assertThat(map.size()).isEqualTo(1); } + + @Test + public void testFastRemoveEmpty() throws InterruptedException, ExecutionException { + LocalCachedMapOptions options = LocalCachedMapOptions.defaults() + .evictionPolicy(EvictionPolicy.NONE) + .cacheSize(3) + .invalidateEntryOnChange(false); + RLocalCachedMap map = redisson.getLocalCachedMap("test", options); + assertThat(map.fastRemove("test")).isZero(); + } + @Test public void testFastPut() {