diff --git a/redisson/src/main/java/org/redisson/RedissonLocalCachedMap.java b/redisson/src/main/java/org/redisson/RedissonLocalCachedMap.java index e30a77824..3f9b7ac8c 100644 --- a/redisson/src/main/java/org/redisson/RedissonLocalCachedMap.java +++ b/redisson/src/main/java/org/redisson/RedissonLocalCachedMap.java @@ -16,6 +16,7 @@ package org.redisson; import io.netty.buffer.ByteBuf; +import io.netty.util.ReferenceCountUtil; import org.redisson.api.LocalCachedMapOptions; import org.redisson.api.LocalCachedMapOptions.ReconnectionStrategy; import org.redisson.api.LocalCachedMapOptions.SyncStrategy; @@ -826,7 +827,14 @@ public class RedissonLocalCachedMap extends RedissonMap implements R continue; } - mapKeys.add(encodeMapKey(value.getKey())); + try { + mapKeys.add(encodeMapKey(value.getKey())); + } catch (Exception e) { + mapKeys.forEach(v -> { + ReferenceCountUtil.safeRelease(v); + }); + throw e; + } result.add((V) value.getValue()); } @@ -869,7 +877,14 @@ public class RedissonLocalCachedMap extends RedissonMap implements R if (value == null) { continue; } - mapKeys.add(encodeMapKey(value.getKey())); + try { + mapKeys.add(encodeMapKey(value.getKey())); + } catch (Exception e) { + mapKeys.forEach(v -> { + ReferenceCountUtil.safeRelease(v); + }); + throw e; + } result.put((K) value.getKey(), (V) value.getValue()); } @@ -925,7 +940,14 @@ public class RedissonLocalCachedMap extends RedissonMap implements R continue; } - mapKeys.add(encodeMapKey(value.getKey())); + try { + mapKeys.add(encodeMapKey(value.getKey())); + } catch (Exception e) { + mapKeys.forEach(v -> { + ReferenceCountUtil.safeRelease(v); + }); + throw e; + } result.add(new AbstractMap.SimpleEntry((K) value.getKey(), (V) value.getValue())); } diff --git a/redisson/src/main/java/org/redisson/RedissonMap.java b/redisson/src/main/java/org/redisson/RedissonMap.java index 38436dcd4..65e4b9b24 100644 --- a/redisson/src/main/java/org/redisson/RedissonMap.java +++ b/redisson/src/main/java/org/redisson/RedissonMap.java @@ -16,6 +16,7 @@ package org.redisson; import io.netty.buffer.ByteBuf; +import io.netty.util.ReferenceCountUtil; import org.redisson.api.*; import org.redisson.api.MapOptions.WriteMode; import org.redisson.api.mapreduce.RMapReduce; @@ -768,13 +769,7 @@ public class RedissonMap extends RedissonExpirable implements RMap { protected RFuture putAllOperationAsync(Map map) { List params = new ArrayList<>(map.size()*2 + 1); params.add(getRawName()); - for (java.util.Map.Entry t : map.entrySet()) { - checkKey(t.getKey()); - checkValue(t.getValue()); - - params.add(encodeMapKey(t.getKey())); - params.add(encodeMapValue(t.getValue())); - } + encodeMapKeys(params, map); RFuture future = commandExecutor.writeAsync(getRawName(), codec, RedisCommands.HMSET, params.toArray()); return future; @@ -1043,6 +1038,23 @@ public class RedissonMap extends RedissonExpirable implements RMap { } } + protected void encodeMapKeys(Collection params, Map map) { + try { + for (java.util.Map.Entry t : map.entrySet()) { + checkKey(t.getKey()); + checkValue(t.getValue()); + + params.add(encodeMapKey(t.getKey())); + params.add(encodeMapValue(t.getValue())); + } + } catch (Exception e) { + params.forEach(v -> { + ReferenceCountUtil.safeRelease(v); + }); + throw e; + } + } + @Override public boolean replace(K key, V oldValue, V newValue) { return get(replaceAsync(key, oldValue, newValue)); @@ -1430,9 +1442,7 @@ public class RedissonMap extends RedissonExpirable implements RMap { protected RFuture> fastRemoveOperationBatchAsync(K... keys) { List args = new ArrayList<>(keys.length); - for (K key : keys) { - args.add(encodeMapKey(key)); - } + encodeMapKeys(args, Arrays.asList(keys)); RFuture> future = commandExecutor.evalWriteAsync(getRawName(), LongCodec.INSTANCE, RedisCommands.EVAL_LIST, "local result = {}; " + @@ -1449,9 +1459,7 @@ public class RedissonMap extends RedissonExpirable implements RMap { protected RFuture fastRemoveOperationAsync(K... keys) { List args = new ArrayList<>(keys.length + 1); args.add(getRawName()); - for (K key : keys) { - args.add(encodeMapKey(key)); - } + encodeMapKeys(args, Arrays.asList(keys)); return commandExecutor.writeAsync(getRawName(), codec, RedisCommands.HDEL, args.toArray()); } diff --git a/redisson/src/main/java/org/redisson/RedissonMapCache.java b/redisson/src/main/java/org/redisson/RedissonMapCache.java index 72ad184c1..12e7093d4 100644 --- a/redisson/src/main/java/org/redisson/RedissonMapCache.java +++ b/redisson/src/main/java/org/redisson/RedissonMapCache.java @@ -227,14 +227,11 @@ public class RedissonMapCache extends RedissonMap implements RMapCac @Override public RFuture> getAllOperationAsync(Set keys) { - List args = new ArrayList(keys.size() + 1); - List plainKeys = new ArrayList(keys.size()); + List args = new ArrayList<>(keys.size() + 1); + List plainKeys = new ArrayList<>(keys); args.add(System.currentTimeMillis()); - for (K key : keys) { - plainKeys.add(key); - args.add(encodeMapKey(key)); - } + encodeMapKeys(args, keys); return commandExecutor.evalWriteAsync(getRawName(), codec, new RedisCommand>("EVAL", new MapValueDecoder(new MapGetAllDecoder(plainKeys, 0))), @@ -1441,10 +1438,8 @@ public class RedissonMapCache extends RedissonMap implements RMapCac @Override protected RFuture> fastRemoveOperationBatchAsync(K... keys) { - List args = new ArrayList(keys.length); - for (K key : keys) { - args.add(encodeMapKey(key)); - } + List args = new ArrayList<>(keys.length); + encodeMapKeys(args, Arrays.asList(keys)); RFuture> future = commandExecutor.evalWriteAsync(getRawName(), LongCodec.INSTANCE, RedisCommands.EVAL_LIST, "local maxSize = tonumber(redis.call('hget', KEYS[6], 'max-size')); " @@ -1475,10 +1470,8 @@ public class RedissonMapCache extends RedissonMap implements RMapCac @Override protected RFuture fastRemoveOperationAsync(K... keys) { - List params = new ArrayList(keys.length); - for (K key : keys) { - params.add(encodeMapKey(key)); - } + List params = new ArrayList<>(keys.length); + encodeMapKeys(params, Arrays.asList(keys)); return commandExecutor.evalWriteAsync(getRawName(), codec, RedisCommands.EVAL_LONG, "local maxSize = tonumber(redis.call('hget', KEYS[6], 'max-size')); " @@ -2082,17 +2075,7 @@ public class RedissonMapCache extends RedissonMap implements RMapCac protected RFuture putAllOperationAsync(Map map) { List params = new ArrayList(map.size()*2 + 1); params.add(System.currentTimeMillis()); - for (java.util.Map.Entry t : map.entrySet()) { - if (t.getKey() == null) { - throw new NullPointerException("map key can't be null"); - } - if (t.getValue() == null) { - throw new NullPointerException("map value can't be null"); - } - - params.add(encodeMapKey(t.getKey())); - params.add(encodeMapValue(t.getValue())); - } + encodeMapKeys(params, map); return commandExecutor.evalWriteAsync(getRawName(), codec, RedisCommands.EVAL_VOID, "local currentTime = tonumber(table.remove(ARGV, 1)); " + // index is the first parameter @@ -2187,17 +2170,7 @@ public class RedissonMapCache extends RedissonMap implements RMapCac ttlTimeout = System.currentTimeMillis() + ttlUnit.toMillis(ttl); } params.add(ttlTimeout); - for (java.util.Map.Entry t : map.entrySet()) { - if (t.getKey() == null) { - throw new NullPointerException("map key can't be null"); - } - if (t.getValue() == null) { - throw new NullPointerException("map value can't be null"); - } - - params.add(encodeMapKey(t.getKey())); - params.add(encodeMapValue(t.getValue())); - } + encodeMapKeys(params, map); return commandExecutor.evalWriteAsync(getRawName(), codec, RedisCommands.EVAL_VOID, "local currentTime = tonumber(table.remove(ARGV, 1)); " + // index is the first parameter diff --git a/redisson/src/main/java/org/redisson/RedissonObject.java b/redisson/src/main/java/org/redisson/RedissonObject.java index 77f64ac26..9f1164635 100644 --- a/redisson/src/main/java/org/redisson/RedissonObject.java +++ b/redisson/src/main/java/org/redisson/RedissonObject.java @@ -16,6 +16,7 @@ package org.redisson; import io.netty.buffer.ByteBuf; +import io.netty.util.ReferenceCountUtil; import org.redisson.api.*; import org.redisson.client.codec.ByteArrayCodec; import org.redisson.client.codec.Codec; @@ -260,8 +261,15 @@ public abstract class RedissonObject implements RObject { } public void encode(Collection params, Collection values) { - for (Object object : values) { - params.add(encode(object)); + try { + for (Object object : values) { + params.add(encode(object)); + } + } catch (Exception e) { + params.forEach(v -> { + ReferenceCountUtil.safeRelease(v); + }); + throw e; } } @@ -282,16 +290,30 @@ public abstract class RedissonObject implements RObject { keyState.release(); } } - + protected void encodeMapKeys(Collection params, Collection values) { - for (Object object : values) { - params.add(encodeMapKey(object)); + try { + for (Object object : values) { + params.add(encodeMapKey(object)); + } + } catch (Exception e) { + params.forEach(v -> { + ReferenceCountUtil.safeRelease(v); + }); + throw e; } } protected void encodeMapValues(Collection params, Collection values) { - for (Object object : values) { - params.add(encodeMapValue(object)); + try { + for (Object object : values) { + params.add(encodeMapValue(object)); + } + } catch (Exception e) { + params.forEach(v -> { + ReferenceCountUtil.safeRelease(v); + }); + throw e; } } diff --git a/redisson/src/main/java/org/redisson/jcache/JCache.java b/redisson/src/main/java/org/redisson/jcache/JCache.java index 2546c3ee0..c6d836bbc 100644 --- a/redisson/src/main/java/org/redisson/jcache/JCache.java +++ b/redisson/src/main/java/org/redisson/jcache/JCache.java @@ -2093,9 +2093,7 @@ public class JCache extends RedissonObject implements Cache, CacheAs params.add(System.currentTimeMillis()); params.add(syncId); - for (Object key : keys) { - params.add(encodeMapKey(key)); - } + encodeMapKeys(params, keys); String script = "local syncs = 0; " + "local values = {}; "