Skip to content

Commit 6e9177b

Browse files
sazzad16chayim
andauthored
[WIP] RESP3 Support (#3293)
Co-authored-by: Chayim <[email protected]>
1 parent 4a8b9e7 commit 6e9177b

31 files changed

+499
-166
lines changed

src/main/java/redis/clients/jedis/BuilderFactory.java

Lines changed: 102 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,12 @@
44
import java.util.*;
55
import java.util.stream.Collectors;
66

7-
import redis.clients.jedis.exceptions.JedisException;
87
import redis.clients.jedis.resps.StreamConsumerFullInfo;
98
import redis.clients.jedis.resps.StreamFullInfo;
109
import redis.clients.jedis.resps.StreamGroupFullInfo;
1110
import redis.clients.jedis.resps.LCSMatchResult.MatchedPosition;
1211
import redis.clients.jedis.resps.LCSMatchResult.Position;
1312
import redis.clients.jedis.resps.*;
14-
import redis.clients.jedis.search.aggr.AggregationResult;
15-
import redis.clients.jedis.timeseries.TSKeyedElements;
16-
import redis.clients.jedis.timeseries.TSElement;
17-
import redis.clients.jedis.timeseries.TSKeyValue;
1813
import redis.clients.jedis.util.DoublePrecision;
1914
import redis.clients.jedis.util.JedisByteHashMap;
2015
import redis.clients.jedis.util.KeyValue;
@@ -116,7 +111,9 @@ public String toString() {
116111
public static final Builder<Double> DOUBLE = new Builder<Double>() {
117112
@Override
118113
public Double build(Object data) {
119-
return DoublePrecision.parseFloatingPointNumber(STRING.build(data));
114+
if (data == null) return null;
115+
else if (data instanceof Double) return (Double) data;
116+
else return DoublePrecision.parseFloatingPointNumber(STRING.build(data));
120117
}
121118

122119
@Override
@@ -129,15 +126,8 @@ public String toString() {
129126
@Override
130127
@SuppressWarnings("unchecked")
131128
public List<Double> build(Object data) {
132-
if (null == data) {
133-
return null;
134-
}
135-
List<byte[]> values = (List<byte[]>) data;
136-
List<Double> doubles = new ArrayList<>(values.size());
137-
for (byte[] value : values) {
138-
doubles.add(DOUBLE.build(value));
139-
}
140-
return doubles;
129+
if (null == data) return null;
130+
return ((List<Object>) data).stream().map(DOUBLE::build).collect(Collectors.toList());
141131
}
142132

143133
@Override
@@ -210,6 +200,7 @@ public String toString() {
210200
}
211201
};
212202

203+
// TODO: remove
213204
public static final Builder<byte[]> BYTE_ARRAY = new Builder<byte[]>() {
214205
@Override
215206
public byte[] build(Object data) {
@@ -222,6 +213,7 @@ public String toString() {
222213
}
223214
};
224215

216+
// TODO: remove
225217
public static final Builder<List<byte[]>> BYTE_ARRAY_LIST = new Builder<List<byte[]>>() {
226218
@Override
227219
@SuppressWarnings("unchecked")
@@ -300,6 +292,26 @@ public String toString() {
300292
}
301293
};
302294

295+
public static final Builder<Map<byte[], byte[]>> BINARY_MAP_FROM_PAIRS = new Builder<Map<byte[], byte[]>>() {
296+
@Override
297+
@SuppressWarnings("unchecked")
298+
public Map<byte[], byte[]> build(Object data) {
299+
final List<Object> list = (List<Object>) data;
300+
final Map<byte[], byte[]> map = new JedisByteHashMap();
301+
for (Object object : list) {
302+
final List<byte[]> flat = (List<byte[]>) object;
303+
map.put(flat.get(0), flat.get(1));
304+
}
305+
306+
return map;
307+
}
308+
309+
@Override
310+
public String toString() {
311+
return "Map<String, String>";
312+
}
313+
};
314+
303315
public static final Builder<String> STRING = new Builder<String>() {
304316
@Override
305317
public String build(Object data) {
@@ -445,7 +457,6 @@ public Tuple build(Object data) {
445457
public String toString() {
446458
return "Tuple";
447459
}
448-
449460
};
450461

451462
public static final Builder<KeyedZSetElement> KEYED_ZSET_ELEMENT = new Builder<KeyedZSetElement>() {
@@ -487,6 +498,20 @@ public String toString() {
487498
}
488499
};
489500

501+
public static final Builder<List<Tuple>> TUPLE_LIST_RESP3 = new Builder<List<Tuple>>() {
502+
@Override
503+
@SuppressWarnings("unchecked")
504+
public List<Tuple> build(Object data) {
505+
if (null == data) return null;
506+
return ((List<Object>) data).stream().map(TUPLE::build).collect(Collectors.toList());
507+
}
508+
509+
@Override
510+
public String toString() {
511+
return "List<Tuple>";
512+
}
513+
};
514+
490515
public static final Builder<Set<Tuple>> TUPLE_ZSET = new Builder<Set<Tuple>>() {
491516
@Override
492517
@SuppressWarnings("unchecked")
@@ -509,14 +534,26 @@ public String toString() {
509534
}
510535
};
511536

537+
public static final Builder<Set<Tuple>> TUPLE_ZSET_RESP3 = new Builder<Set<Tuple>>() {
538+
@Override
539+
@SuppressWarnings("unchecked")
540+
public Set<Tuple> build(Object data) {
541+
if (null == data) return null;
542+
return ((List<Object>) data).stream().map(TUPLE::build).collect(Collectors.toCollection(LinkedHashSet::new));
543+
}
544+
545+
@Override
546+
public String toString() {
547+
return "ZSet<Tuple>";
548+
}
549+
};
550+
512551
private static final Builder<List<Tuple>> TUPLE_LIST_FROM_PAIRS = new Builder<List<Tuple>>() {
513552
@Override
514553
@SuppressWarnings("unchecked")
515554
public List<Tuple> build(Object data) {
516555
if (data == null) return null;
517-
return ((List<Object>) data).stream()
518-
.map(o -> (List<Object>) o).map(p -> TUPLE.build(p))
519-
.collect(Collectors.toList());
556+
return ((List<List<Object>>) data).stream().map(TUPLE::build).collect(Collectors.toList());
520557
}
521558

522559
@Override
@@ -911,7 +948,8 @@ public String toString() {
911948
/**
912949
* Create an Access Control Log Entry Result of ACL LOG command
913950
*/
914-
public static final Builder<List<AccessControlLogEntry>> ACCESS_CONTROL_LOG_ENTRY_LIST = new Builder<List<AccessControlLogEntry>>() {
951+
public static final Builder<List<AccessControlLogEntry>> ACCESS_CONTROL_LOG_ENTRY_LIST
952+
= new Builder<List<AccessControlLogEntry>>() {
915953

916954
private final Map<String, Builder> mappingFunctions = createDecoderMap();
917955

@@ -923,7 +961,7 @@ private Map<String, Builder> createDecoderMap() {
923961
tempMappingFunctions.put(AccessControlLogEntry.CONTEXT, STRING);
924962
tempMappingFunctions.put(AccessControlLogEntry.OBJECT, STRING);
925963
tempMappingFunctions.put(AccessControlLogEntry.USERNAME, STRING);
926-
tempMappingFunctions.put(AccessControlLogEntry.AGE_SECONDS, STRING);
964+
// tempMappingFunctions.put(AccessControlLogEntry.AGE_SECONDS, STRING);
927965
tempMappingFunctions.put(AccessControlLogEntry.CLIENT_INFO, STRING);
928966

929967
return tempMappingFunctions;
@@ -941,7 +979,8 @@ public List<AccessControlLogEntry> build(Object data) {
941979
for (List<Object> logEntryData : logEntries) {
942980
Iterator<Object> logEntryDataIterator = logEntryData.iterator();
943981
AccessControlLogEntry accessControlLogEntry = new AccessControlLogEntry(
944-
createMapFromDecodingFunctions(logEntryDataIterator, mappingFunctions));
982+
createMapFromDecodingFunctions(logEntryDataIterator, mappingFunctions,
983+
BACKUP_BUILDERS_FOR_DECODING_FUNCTIONS));
945984
list.add(accessControlLogEntry);
946985
}
947986
return list;
@@ -1108,17 +1147,39 @@ public String toString() {
11081147
= new Builder<List<Map.Entry<String, List<StreamEntry>>>>() {
11091148
@Override
11101149
public List<Map.Entry<String, List<StreamEntry>>> build(Object data) {
1111-
if (data == null) {
1112-
return null;
1113-
}
1114-
List<Object> streams = (List<Object>) data;
1150+
if (data == null) return null;
1151+
List streamObjects = (List) data;
11151152

1116-
List<Map.Entry<String, List<StreamEntry>>> result = new ArrayList<>(streams.size());
1117-
for (Object streamObj : streams) {
1153+
List<Map.Entry<String, List<StreamEntry>>> result = new ArrayList<>(streamObjects.size());
1154+
for (Object streamObj : streamObjects) {
11181155
List<Object> stream = (List<Object>) streamObj;
1119-
String streamId = SafeEncoder.encode((byte[]) stream.get(0));
1120-
List<StreamEntry> streamEntries = BuilderFactory.STREAM_ENTRY_LIST.build(stream.get(1));
1121-
result.add(new AbstractMap.SimpleEntry<>(streamId, streamEntries));
1156+
String streamKey = STRING.build(stream.get(0));
1157+
List<StreamEntry> streamEntries = STREAM_ENTRY_LIST.build(stream.get(1));
1158+
result.add(new AbstractMap.SimpleEntry<>(streamKey, streamEntries));
1159+
}
1160+
1161+
return result;
1162+
}
1163+
1164+
@Override
1165+
public String toString() {
1166+
return "List<Entry<String, List<StreamEntry>>>";
1167+
}
1168+
};
1169+
1170+
public static final Builder<List<Map.Entry<String, List<StreamEntry>>>> STREAM_READ_RESPONSE_RESP3
1171+
= new Builder<List<Map.Entry<String, List<StreamEntry>>>>() {
1172+
@Override
1173+
public List<Map.Entry<String, List<StreamEntry>>> build(Object data) {
1174+
if (data == null) return null;
1175+
List streamObjects = (List) data;
1176+
1177+
List<Map.Entry<String, List<StreamEntry>>> result = new ArrayList<>(streamObjects.size() / 2);
1178+
Iterator iter = streamObjects.iterator();
1179+
while (iter.hasNext()) {
1180+
String streamKey = STRING.build(iter.next());
1181+
List<StreamEntry> streamEntries = STREAM_ENTRY_LIST.build(iter.next());
1182+
result.add(new AbstractMap.SimpleEntry<>(streamKey, streamEntries));
11221183
}
11231184

11241185
return result;
@@ -1436,8 +1497,16 @@ public String toString() {
14361497
}
14371498
};
14381499

1500+
private static final List<Builder> BACKUP_BUILDERS_FOR_DECODING_FUNCTIONS
1501+
= Arrays.asList(STRING, LONG, DOUBLE);
1502+
14391503
private static Map<String, Object> createMapFromDecodingFunctions(Iterator<Object> iterator,
14401504
Map<String, Builder> mappingFunctions) {
1505+
return createMapFromDecodingFunctions(iterator, mappingFunctions, null);
1506+
}
1507+
1508+
private static Map<String, Object> createMapFromDecodingFunctions(Iterator<Object> iterator,
1509+
Map<String, Builder> mappingFunctions, Collection<Builder> backupBuilders) {
14411510

14421511
Map<String, Object> resultMap = new HashMap<>();
14431512
while (iterator.hasNext()) {
@@ -1447,13 +1516,13 @@ private static Map<String, Object> createMapFromDecodingFunctions(Iterator<Objec
14471516
resultMap.put(mapKey, mappingFunctions.get(mapKey).build(iterator.next()));
14481517
} else { // For future - if we don't find an element in our builder map
14491518
Object unknownData = iterator.next();
1450-
for (Builder b : mappingFunctions.values()) {
1519+
Collection<Builder> builders = backupBuilders != null ? backupBuilders : mappingFunctions.values();
1520+
for (Builder b : builders) {
14511521
try {
14521522
resultMap.put(mapKey, b.build(unknownData));
14531523
break;
14541524
} catch (ClassCastException e) {
14551525
// We continue with next builder
1456-
14571526
}
14581527
}
14591528
}

src/main/java/redis/clients/jedis/ClusterPipeline.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import redis.clients.jedis.providers.ClusterConnectionProvider;
66
import redis.clients.jedis.util.IOUtils;
77

8+
// TODO: RESP3
89
public class ClusterPipeline extends MultiNodePipelineBase {
910

1011
private final ClusterConnectionProvider provider;

0 commit comments

Comments
 (0)