From 2491156c1a2647a32fa21a055eecbbd33c8cc4fd Mon Sep 17 00:00:00 2001 From: seakider Date: Tue, 2 Jul 2024 00:30:42 +0800 Subject: [PATCH] Fixed - method containsAll execute incorrect or caused RedisException Signed-off-by: seakider --- .../java/org/redisson/BaseRedissonList.java | 2 +- .../org/redisson/RedissonDelayedQueue.java | 2 +- .../redisson/RedissonListMultimapValues.java | 6 ++--- .../redisson/RedissonSetMultimapValues.java | 6 ++--- .../java/org/redisson/RedissonSubList.java | 8 +++---- .../redisson/RedissonDelayedQueueTest.java | 5 +++- .../RedissonListMultimapCacheTest.java | 16 +++++++++++++ .../java/org/redisson/RedissonListTest.java | 23 +++++++++++++++++++ .../RedissonSetMultimapCacheTest.java | 17 +++++++++++++- 9 files changed, 71 insertions(+), 14 deletions(-) diff --git a/redisson/src/main/java/org/redisson/BaseRedissonList.java b/redisson/src/main/java/org/redisson/BaseRedissonList.java index 098384329..e282484f9 100644 --- a/redisson/src/main/java/org/redisson/BaseRedissonList.java +++ b/redisson/src/main/java/org/redisson/BaseRedissonList.java @@ -139,7 +139,7 @@ public class BaseRedissonList extends RedissonExpirable { return commandExecutor.evalReadAsync(getRawName(), codec, RedisCommands.EVAL_BOOLEAN, "local items = redis.call('lrange', KEYS[1], 0, -1) " + "for i=1, #items do " + - "for j = 1, #ARGV, 1 do " + + "for j = #ARGV, 1, -1 do " + "if items[i] == ARGV[j] then " + "table.remove(ARGV, j) " + "end " + diff --git a/redisson/src/main/java/org/redisson/RedissonDelayedQueue.java b/redisson/src/main/java/org/redisson/RedissonDelayedQueue.java index cc9d12f66..517fb6b65 100644 --- a/redisson/src/main/java/org/redisson/RedissonDelayedQueue.java +++ b/redisson/src/main/java/org/redisson/RedissonDelayedQueue.java @@ -320,7 +320,7 @@ public class RedissonDelayedQueue extends RedissonExpirable implements RDelay + "local v = redis.call('lindex', KEYS[1], i);" + "local randomId, value = struct.unpack('Bc0Lc0', v);" - + "for j = 1, #ARGV, 1 do " + + "for j = #ARGV, 1, -1 do " + "if value == ARGV[j] then " + "table.remove(ARGV, j) " + "end; " diff --git a/redisson/src/main/java/org/redisson/RedissonListMultimapValues.java b/redisson/src/main/java/org/redisson/RedissonListMultimapValues.java index 10b3043bd..cc1eaab2a 100644 --- a/redisson/src/main/java/org/redisson/RedissonListMultimapValues.java +++ b/redisson/src/main/java/org/redisson/RedissonListMultimapValues.java @@ -232,7 +232,7 @@ public class RedissonListMultimapValues extends RedissonExpirable implements + "end; " + "local items = redis.call('lrange', KEYS[2], 0, -1);" + "for i = 1, #items, 1 do " + - "for j = 2, #ARGV, 1 do " + "for j = #ARGV, 3, -1 do " + "if ARGV[j] == items[i] " + "then table.remove(ARGV, j) end " + "end; " @@ -285,7 +285,7 @@ public class RedissonListMultimapValues extends RedissonExpirable implements + "end; " + "local v = 0 " + - "for i = 2, #ARGV, 1 do " + "for i = 3, #ARGV, 1 do " + "if redis.call('lrem', KEYS[2], 0, ARGV[i]) == 1 " + "then v = 1 end " +"end " @@ -326,7 +326,7 @@ public class RedissonListMultimapValues extends RedissonExpirable implements + "while i <= #s do " + "local element = s[i]; " + "local isInAgrs = false; " - + "for j = 2, #ARGV, 1 do " + + "for j = 3, #ARGV, 1 do " + "if ARGV[j] == element then " + "isInAgrs = true; " + "break; " diff --git a/redisson/src/main/java/org/redisson/RedissonSetMultimapValues.java b/redisson/src/main/java/org/redisson/RedissonSetMultimapValues.java index 9b0e2cfbd..84daea0f4 100644 --- a/redisson/src/main/java/org/redisson/RedissonSetMultimapValues.java +++ b/redisson/src/main/java/org/redisson/RedissonSetMultimapValues.java @@ -454,7 +454,7 @@ public class RedissonSetMultimapValues extends RedissonExpirable implements R + "end; " + "local s = redis.call('smembers', KEYS[2]);" + "for i = 1, #s, 1 do " + - "for j = 2, #ARGV, 1 do " + "for j = #ARGV, 3, -1 do " + "if ARGV[j] == s[i] " + "then table.remove(ARGV, j) end " + "end; " @@ -536,7 +536,7 @@ public class RedissonSetMultimapValues extends RedissonExpirable implements R + "while i <= #s do " + "local element = s[i] " + "local isInAgrs = false " - + "for j = 2, #ARGV, 1 do " + + "for j = 3, #ARGV, 1 do " + "if ARGV[j] == element then " + "isInAgrs = true " + "break " @@ -570,7 +570,7 @@ public class RedissonSetMultimapValues extends RedissonExpirable implements R + "end; " + "local v = 0 " + - "for i = 2, #ARGV, 1 do " + "for i = 3, #ARGV, 1 do " + "if redis.call('srem', KEYS[2], ARGV[i]) == 1 " + "then v = 1 end " +"end " diff --git a/redisson/src/main/java/org/redisson/RedissonSubList.java b/redisson/src/main/java/org/redisson/RedissonSubList.java index 65b5c95fd..7eeb8d550 100644 --- a/redisson/src/main/java/org/redisson/RedissonSubList.java +++ b/redisson/src/main/java/org/redisson/RedissonSubList.java @@ -87,10 +87,10 @@ public class RedissonSubList extends RedissonList implements RList { encode(params, c); return commandExecutor.evalReadAsync(getRawName(), codec, RedisCommands.EVAL_BOOLEAN, "local fromIndex = table.remove(ARGV, 1);" + - "local toIndex = table.remove(ARGV, 2);" + + "local toIndex = table.remove(ARGV, 1);" + "local items = redis.call('lrange', KEYS[1], tonumber(fromIndex), tonumber(toIndex)) " + "for i=1, #items do " + - "for j = 1, #ARGV, 1 do " + + "for j = #ARGV, 1, -1 do " + "if items[i] == ARGV[j] then " + "table.remove(ARGV, j) " + "end " + @@ -163,7 +163,7 @@ public class RedissonSubList extends RedissonList implements RList { return commandExecutor.evalWriteAsync(getRawName(), codec, RedisCommands.EVAL_BOOLEAN, "local v = 0; " + "local fromIndex = table.remove(ARGV, 1);" + - "local toIndex = table.remove(ARGV, 2);" + + "local toIndex = table.remove(ARGV, 1);" + "local count = table.remove(ARGV, 3);" + "local items = redis.call('lrange', KEYS[1], fromIndex, toIndex); " + @@ -189,7 +189,7 @@ public class RedissonSubList extends RedissonList implements RList { return commandExecutor.evalWriteAsync(getRawName(), codec, RedisCommands.EVAL_BOOLEAN, "local changed = 0 " + "local fromIndex = table.remove(ARGV, 1);" + - "local toIndex = table.remove(ARGV, 2);" + + "local toIndex = table.remove(ARGV, 1);" + "local items = redis.call('lrange', KEYS[1], fromIndex, toIndex) " + "local i = 1 " + "while i <= #items do " diff --git a/redisson/src/test/java/org/redisson/RedissonDelayedQueueTest.java b/redisson/src/test/java/org/redisson/RedissonDelayedQueueTest.java index b455eb536..2afd044f1 100644 --- a/redisson/src/test/java/org/redisson/RedissonDelayedQueueTest.java +++ b/redisson/src/test/java/org/redisson/RedissonDelayedQueueTest.java @@ -105,7 +105,10 @@ public class RedissonDelayedQueueTest extends RedisDockerTest { assertThat(dealyedQueue.containsAll(Arrays.asList(1, 2))).isTrue(); assertThat(dealyedQueue.containsAll(Arrays.asList(1, 2, 4))).isFalse(); - + + assertThat(dealyedQueue.containsAll(Arrays.asList(1, 1))).isTrue(); + assertThat(dealyedQueue.containsAll(Arrays.asList(1, 2, 1))).isTrue(); + dealyedQueue.destroy(); } diff --git a/redisson/src/test/java/org/redisson/RedissonListMultimapCacheTest.java b/redisson/src/test/java/org/redisson/RedissonListMultimapCacheTest.java index 16b754605..7d605c96d 100644 --- a/redisson/src/test/java/org/redisson/RedissonListMultimapCacheTest.java +++ b/redisson/src/test/java/org/redisson/RedissonListMultimapCacheTest.java @@ -4,6 +4,7 @@ import org.junit.jupiter.api.Test; import org.redisson.api.RMultimapCache; import java.util.Arrays; +import java.util.List; import static org.assertj.core.api.Assertions.assertThat; @@ -34,5 +35,20 @@ public class RedissonListMultimapCacheTest extends RedissonBaseMultimapCacheTest assertThat(multimap.get("1").retainAll(Arrays.asList("1"))).isTrue(); assertThat(multimap.get("1").removeAll(Arrays.asList("1"))).isTrue(); } + + @Test + public void testContainsAll() { + RMultimapCache multimap = getMultimapCache("test"); + multimap.put("1", "1"); + multimap.put("1", "2"); + multimap.put("1", "3"); + multimap.put("1", "3"); + + assertThat(multimap.get("1").containsAll(List.of("1", "2"))).isTrue(); + assertThat(multimap.get("1").containsAll(List.of("1", "2", "4"))).isFalse(); + assertThat(multimap.get("1").containsAll(List.of("1", "2", "1"))).isTrue(); + assertThat(multimap.get("1").containsAll(List.of("1", "1"))).isTrue(); + + } } diff --git a/redisson/src/test/java/org/redisson/RedissonListTest.java b/redisson/src/test/java/org/redisson/RedissonListTest.java index 660f6ecbf..72cb61e1e 100644 --- a/redisson/src/test/java/org/redisson/RedissonListTest.java +++ b/redisson/src/test/java/org/redisson/RedissonListTest.java @@ -757,6 +757,26 @@ public class RedissonListTest extends RedisDockerTest { Assertions.assertEquals(8, index); } + @Test + public void testSubListContainsAll() { + List list = redisson.getList("list"); + list.add(1); + list.add(2); + list.add(3); + list.add(4); + list.add(5); + list.add(6); + list.add(7); + list.add(8); + list.add(9); + list.add(10); + + List subList = list.subList(3, 7); + assertThat(subList.containsAll(List.of(4, 5))).isTrue(); + assertThat(subList.containsAll(List.of(4, 4))).isTrue(); + assertThat(subList.containsAll(List.of(4, 5, 4))).isTrue(); + } + @Test public void testSubListMiddle() { List list = redisson.getList("list"); @@ -1160,6 +1180,9 @@ public class RedissonListTest extends RedisDockerTest { Assertions.assertTrue(list.containsAll(Arrays.asList(30, 11))); Assertions.assertFalse(list.containsAll(Arrays.asList(30, 711, 11))); Assertions.assertTrue(list.containsAll(Arrays.asList(30))); + + Assertions.assertTrue(list.containsAll(Arrays.asList(30, 30))); + Assertions.assertTrue(list.containsAll(Arrays.asList(30, 11, 30))); } @Test diff --git a/redisson/src/test/java/org/redisson/RedissonSetMultimapCacheTest.java b/redisson/src/test/java/org/redisson/RedissonSetMultimapCacheTest.java index 995675e4a..3839a113a 100644 --- a/redisson/src/test/java/org/redisson/RedissonSetMultimapCacheTest.java +++ b/redisson/src/test/java/org/redisson/RedissonSetMultimapCacheTest.java @@ -3,6 +3,7 @@ package org.redisson; import static org.assertj.core.api.Assertions.assertThat; import java.util.Arrays; +import java.util.List; import org.junit.jupiter.api.Test; import org.redisson.api.RMultimapCache; @@ -32,5 +33,19 @@ public class RedissonSetMultimapCacheTest extends RedissonBaseMultimapCacheTest assertThat(multimap.get("1").retainAll(Arrays.asList("1"))).isTrue(); assertThat(multimap.get("1").removeAll(Arrays.asList("1"))).isTrue(); } - + + @Test + public void testContainsAll() { + RMultimapCache multimap = getMultimapCache("test"); + multimap.put("1", "1"); + multimap.put("1", "2"); + multimap.put("1", "3"); + multimap.put("1", "3"); + + assertThat(multimap.get("1").containsAll(List.of("1", "2"))).isTrue(); + assertThat(multimap.get("1").containsAll(List.of("1", "2", "4"))).isFalse(); + assertThat(multimap.get("1").containsAll(List.of("1", "2", "1"))).isTrue(); + assertThat(multimap.get("1").containsAll(List.of("1", "1"))).isTrue(); + + } }