From 8ed4703d46cdc73cb5989469158e9d91047be605 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20B=C3=BChler?= Date: Fri, 6 Apr 2018 23:22:06 +0200 Subject: [PATCH] DATAREDIS-803 - Retrieve DefaultRedisMap.entrySet() via HGETALL. Redis has a limitation of 1024 * 1024 parameters]() for bulk operations. To receive more than 1024 * 1024 - 1 entries with entrySet(), we can directly use the HGETALL command instead of first fetching the keys with HKEYS and then fetching the values with HMGET. See also: https://github.com/antirez/redis/blob/4.0.9/src/networking.c#L1200 Original pull request: #326. --- .../support/collections/DefaultRedisMap.java | 17 ++++---------- .../collections/AbstractRedisMapTests.java | 23 +++++++++++++++++++ 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/springframework/data/redis/support/collections/DefaultRedisMap.java b/src/main/java/org/springframework/data/redis/support/collections/DefaultRedisMap.java index 39edb7e08..161d6bcfb 100644 --- a/src/main/java/org/springframework/data/redis/support/collections/DefaultRedisMap.java +++ b/src/main/java/org/springframework/data/redis/support/collections/DefaultRedisMap.java @@ -38,6 +38,7 @@ import org.springframework.lang.Nullable; * * @author Costin Leau * @author Christoph Strobl + * @author Christian Bühler */ public class DefaultRedisMap implements RedisMap { @@ -156,19 +157,9 @@ public class DefaultRedisMap implements RedisMap { @Override public Set> entrySet() { - Set keySet = keySet(); - checkResult(keySet); - Collection multiGet = hashOps.multiGet(keySet); - - Iterator keys = keySet.iterator(); - Iterator values = multiGet.iterator(); - - Set> entries = new LinkedHashSet<>(); - while (keys.hasNext()) { - entries.add(new DefaultRedisMapEntry(keys.next(), values.next())); - } - - return entries; + Map entries = hashOps.entries(); + checkResult(entries); + return entries.entrySet(); } /* diff --git a/src/test/java/org/springframework/data/redis/support/collections/AbstractRedisMapTests.java b/src/test/java/org/springframework/data/redis/support/collections/AbstractRedisMapTests.java index 424651b05..e1a9ce559 100644 --- a/src/test/java/org/springframework/data/redis/support/collections/AbstractRedisMapTests.java +++ b/src/test/java/org/springframework/data/redis/support/collections/AbstractRedisMapTests.java @@ -25,6 +25,7 @@ import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.Map; @@ -62,6 +63,7 @@ import org.springframework.test.annotation.IfProfileValue; * @author Jennifer Hickey * @author Christoph Strobl * @author Thomas Darimont + * @author Christian Bühler */ @RunWith(Parameterized.class) public abstract class AbstractRedisMapTests { @@ -396,6 +398,27 @@ public abstract class AbstractRedisMapTests { assertThat(values, not(hasItem(v2))); } + @Test // DATAREDIS-803 + @IfProfileValue(name = "runLongTests", value = "true") + public void testBigEntrySet() { + + Set> entries = map.entrySet(); + assertTrue(entries.isEmpty()); + + for (int j = 0; j < 2; j++) { + Map m = new HashMap<>(); + for (int i = 0; i < 1024 * 1024 / 2 - 1; i++) { + m.put(getKey(), getValue()); + } + map.putAll(m); + } + map.put(getKey(), getValue()); + + entries = map.entrySet(); + + assertEquals(1024 * 1024 - 1, entries.size()); + } + @Test public void testPutIfAbsent() {