Skip to content

Commit d1f8201

Browse files
DATAREDIS-803 - Work around Redis parameter limitation.
Redis has a [limitation of 1024 * 1024 parameters](https://github.com/antirez/redis/blob/4.0.9/src/networking.c#L1200) for bulk operations. To insert more than 1024 * 1024 / 2 - 1 entries with putAll(), they need to be split up in multiple calls. To reveive 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.
1 parent e0b73c7 commit d1f8201

File tree

2 files changed

+27
-13
lines changed

2 files changed

+27
-13
lines changed

src/main/java/org/springframework/data/redis/support/collections/DefaultRedisMap.java

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
*
3939
* @author Costin Leau
4040
* @author Christoph Strobl
41+
* @author Christian Bühler
4142
*/
4243
public class DefaultRedisMap<K, V> implements RedisMap<K, V> {
4344

@@ -156,19 +157,9 @@ public boolean containsValue(Object value) {
156157
@Override
157158
public Set<java.util.Map.Entry<K, V>> entrySet() {
158159

159-
Set<K> keySet = keySet();
160-
checkResult(keySet);
161-
Collection<V> multiGet = hashOps.multiGet(keySet);
162-
163-
Iterator<K> keys = keySet.iterator();
164-
Iterator<V> values = multiGet.iterator();
165-
166-
Set<Map.Entry<K, V>> entries = new LinkedHashSet<>();
167-
while (keys.hasNext()) {
168-
entries.add(new DefaultRedisMapEntry(keys.next(), values.next()));
169-
}
170-
171-
return entries;
160+
Map<K, V> entries = hashOps.entries();
161+
checkResult(entries);
162+
return entries.entrySet();
172163
}
173164

174165
/*

src/test/java/org/springframework/data/redis/support/collections/AbstractRedisMapTests.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.util.ArrayList;
2626
import java.util.Collection;
2727
import java.util.Collections;
28+
import java.util.HashMap;
2829
import java.util.LinkedHashMap;
2930
import java.util.LinkedHashSet;
3031
import java.util.Map;
@@ -62,6 +63,7 @@
6263
* @author Jennifer Hickey
6364
* @author Christoph Strobl
6465
* @author Thomas Darimont
66+
* @author Christian Bühler
6567
*/
6668
@RunWith(Parameterized.class)
6769
public abstract class AbstractRedisMapTests<K, V> {
@@ -396,6 +398,27 @@ public void testEntrySet() {
396398
assertThat(values, not(hasItem(v2)));
397399
}
398400

401+
@Test // DATAREDIS-803
402+
@IfProfileValue(name = "runLongTests", value = "true")
403+
public void testBigEntrySet() {
404+
405+
Set<Entry<K, V>> entries = map.entrySet();
406+
assertTrue(entries.isEmpty());
407+
408+
for (int j = 0; j < 2; j++) {
409+
Map<K, V> m = new HashMap<>();
410+
for (int i = 0; i < 1024 * 1024 / 2 - 1; i++) {
411+
m.put(getKey(), getValue());
412+
}
413+
map.putAll(m);
414+
}
415+
map.put(getKey(), getValue());
416+
417+
entries = map.entrySet();
418+
419+
assertEquals(1024 * 1024 - 1, entries.size());
420+
}
421+
399422
@Test
400423
public void testPutIfAbsent() {
401424

0 commit comments

Comments
 (0)