Skip to content

Commit cd9346a

Browse files
authored
Change FT.PROFILE to return generic object (#4067)
* Change FT.PROFILE to return generic object * Handle FT.PROFILE Results for both Redis 7 and 8
1 parent 8da5104 commit cd9346a

11 files changed

+145
-381
lines changed

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

+34-15
Original file line numberDiff line numberDiff line change
@@ -3434,7 +3434,7 @@ public final CommandObject<String> ftCursorDel(String indexName, long cursorId)
34343434
.key(indexName).add(cursorId), BuilderFactory.STRING);
34353435
}
34363436

3437-
public final CommandObject<Map.Entry<AggregationResult, Map<String, Object>>> ftProfileAggregate(
3437+
public final CommandObject<Map.Entry<AggregationResult, ProfilingInfo>> ftProfileAggregate(
34383438
String indexName, FTProfileParams profileParams, AggregationBuilder aggr) {
34393439
return new CommandObject<>(checkAndRoundRobinSearchCommand(SearchCommand.PROFILE, indexName)
34403440
.add(SearchKeyword.AGGREGATE).addParams(profileParams).add(SearchKeyword.QUERY)
@@ -3443,7 +3443,7 @@ public final CommandObject<Map.Entry<AggregationResult, Map<String, Object>>> ft
34433443
: AggregationResult.SEARCH_AGGREGATION_RESULT_WITH_CURSOR));
34443444
}
34453445

3446-
public final CommandObject<Map.Entry<SearchResult, Map<String, Object>>> ftProfileSearch(
3446+
public final CommandObject<Map.Entry<SearchResult, ProfilingInfo>> ftProfileSearch(
34473447
String indexName, FTProfileParams profileParams, Query query) {
34483448
return new CommandObject<>(checkAndRoundRobinSearchCommand(SearchCommand.PROFILE, indexName)
34493449
.add(SearchKeyword.SEARCH).addParams(profileParams).add(SearchKeyword.QUERY)
@@ -3452,7 +3452,7 @@ public final CommandObject<Map.Entry<SearchResult, Map<String, Object>>> ftProfi
34523452
() -> new SearchResultBuilder(!query.getNoContent(), query.getWithScores(), true))));
34533453
}
34543454

3455-
public final CommandObject<Map.Entry<SearchResult, Map<String, Object>>> ftProfileSearch(
3455+
public final CommandObject<Map.Entry<SearchResult, ProfilingInfo>> ftProfileSearch(
34563456
String indexName, FTProfileParams profileParams, String query, FTSearchParams searchParams) {
34573457
return new CommandObject<>(checkAndRoundRobinSearchCommand(SearchCommand.PROFILE, indexName)
34583458
.add(SearchKeyword.SEARCH).addParams(profileParams).add(SearchKeyword.QUERY).add(query)
@@ -4461,32 +4461,51 @@ public void setDefaultSearchDialect(int dialect) {
44614461
this.searchDialect.set(dialect);
44624462
}
44634463

4464-
private class SearchProfileResponseBuilder<T> extends Builder<Map.Entry<T, Map<String, Object>>> {
4464+
private class SearchProfileResponseBuilder<T> extends Builder<Map.Entry<T, ProfilingInfo>> {
44654465

4466-
private static final String PROFILE_STR = "profile";
4466+
private static final String PROFILE_STR_REDIS7 = "profile";
4467+
private static final String PROFILE_STR_REDIS8 = "Profile";
4468+
private static final String RESULTS_STR_REDIS7 = "results";
4469+
private static final String RESULTS_STR_REDIS8 = "Results";
44674470

4468-
private final Builder<T> replyBuilder;
4471+
private final Builder<T> resultsBuilder;
44694472

4470-
public SearchProfileResponseBuilder(Builder<T> replyBuilder) {
4471-
this.replyBuilder = replyBuilder;
4473+
public SearchProfileResponseBuilder(Builder<T> resultsBuilder) {
4474+
this.resultsBuilder = resultsBuilder;
44724475
}
44734476

44744477
@Override
4475-
public Map.Entry<T, Map<String, Object>> build(Object data) {
4478+
public Map.Entry<T, ProfilingInfo> build(Object data) {
44764479
List list = (List) data;
44774480
if (list == null || list.isEmpty()) return null;
44784481

4479-
if (list.get(0) instanceof KeyValue) {
4482+
if (list.get(0) instanceof KeyValue) { // RESP3
4483+
Object resultsData = null, profileData = null;
4484+
44804485
for (KeyValue keyValue : (List<KeyValue>) data) {
4481-
if (PROFILE_STR.equals(BuilderFactory.STRING.build(keyValue.getKey()))) {
4482-
return KeyValue.of(replyBuilder.build(data),
4483-
BuilderFactory.AGGRESSIVE_ENCODED_OBJECT_MAP.build(keyValue.getValue()));
4486+
String keyStr = BuilderFactory.STRING.build(keyValue.getKey());
4487+
switch (keyStr) {
4488+
case PROFILE_STR_REDIS7:
4489+
case PROFILE_STR_REDIS8:
4490+
profileData = keyValue.getValue();
4491+
break;
4492+
case RESULTS_STR_REDIS7:
4493+
resultsData = data;
4494+
break;
4495+
case RESULTS_STR_REDIS8:
4496+
resultsData = keyValue.getValue();
4497+
break;
44844498
}
44854499
}
4500+
4501+
assert resultsData != null : "Could not detect Results data.";
4502+
assert profileData != null : "Could not detect Profile data.";
4503+
return KeyValue.of(resultsBuilder.build(resultsData),
4504+
ProfilingInfo.PROFILING_INFO_BUILDER.build(profileData));
44864505
}
44874506

4488-
return KeyValue.of(replyBuilder.build(list.get(0)),
4489-
SearchBuilderFactory.SEARCH_PROFILE_PROFILE.build(list.get(1)));
4507+
return KeyValue.of(resultsBuilder.build(list.get(0)),
4508+
ProfilingInfo.PROFILING_INFO_BUILDER.build(list.get(1)));
44904509
}
44914510
}
44924511

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -3985,19 +3985,19 @@ public FtAggregateIteration ftAggregateIteration(String indexName, AggregationBu
39853985
}
39863986

39873987
@Override
3988-
public Map.Entry<AggregationResult, Map<String, Object>> ftProfileAggregate(String indexName,
3988+
public Map.Entry<AggregationResult, ProfilingInfo> ftProfileAggregate(String indexName,
39893989
FTProfileParams profileParams, AggregationBuilder aggr) {
39903990
return executeCommand(commandObjects.ftProfileAggregate(indexName, profileParams, aggr));
39913991
}
39923992

39933993
@Override
3994-
public Map.Entry<SearchResult, Map<String, Object>> ftProfileSearch(String indexName,
3994+
public Map.Entry<SearchResult, ProfilingInfo> ftProfileSearch(String indexName,
39953995
FTProfileParams profileParams, Query query) {
39963996
return executeCommand(commandObjects.ftProfileSearch(indexName, profileParams, query));
39973997
}
39983998

39993999
@Override
4000-
public Map.Entry<SearchResult, Map<String, Object>> ftProfileSearch(String indexName,
4000+
public Map.Entry<SearchResult, ProfilingInfo> ftProfileSearch(String indexName,
40014001
FTProfileParams profileParams, String query, FTSearchParams searchParams) {
40024002
return executeCommand(commandObjects.ftProfileSearch(indexName, profileParams, query, searchParams));
40034003
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package redis.clients.jedis.search;
2+
3+
import static redis.clients.jedis.BuilderFactory.AGGRESSIVE_ENCODED_OBJECT;
4+
5+
import redis.clients.jedis.Builder;
6+
7+
public class ProfilingInfo {
8+
9+
private final Object profilingInfo;
10+
11+
private ProfilingInfo(Object profilingInfo) {
12+
this.profilingInfo = profilingInfo;
13+
}
14+
15+
public Object getProfilingInfo() {
16+
return profilingInfo;
17+
}
18+
19+
@Override
20+
public String toString() {
21+
return String.valueOf(profilingInfo);
22+
}
23+
24+
public static final Builder<ProfilingInfo> PROFILING_INFO_BUILDER
25+
= new Builder<ProfilingInfo>() {
26+
@Override
27+
public ProfilingInfo build(Object data) {
28+
return new ProfilingInfo(AGGRESSIVE_ENCODED_OBJECT.build(data));
29+
}
30+
};
31+
}

src/main/java/redis/clients/jedis/search/RediSearchCommands.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,13 @@ default SearchResult ftSearch(String indexName) {
7474

7575
String ftCursorDel(String indexName, long cursorId);
7676

77-
Map.Entry<AggregationResult, Map<String, Object>> ftProfileAggregate(String indexName,
77+
Map.Entry<AggregationResult, ProfilingInfo> ftProfileAggregate(String indexName,
7878
FTProfileParams profileParams, AggregationBuilder aggr);
7979

80-
Map.Entry<SearchResult, Map<String, Object>> ftProfileSearch(String indexName,
80+
Map.Entry<SearchResult, ProfilingInfo> ftProfileSearch(String indexName,
8181
FTProfileParams profileParams, Query query);
8282

83-
Map.Entry<SearchResult, Map<String, Object>> ftProfileSearch(String indexName,
83+
Map.Entry<SearchResult, ProfilingInfo> ftProfileSearch(String indexName,
8484
FTProfileParams profileParams, String query, FTSearchParams searchParams);
8585

8686
String ftSynUpdate(String indexName, String synonymGroupId, String... terms);

src/main/java/redis/clients/jedis/search/SearchBuilderFactory.java

-100
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import static redis.clients.jedis.BuilderFactory.STRING;
44

5-
import java.util.ArrayList;
65
import java.util.Collections;
76
import java.util.HashMap;
87
import java.util.LinkedHashMap;
@@ -12,109 +11,10 @@
1211

1312
import redis.clients.jedis.Builder;
1413
import redis.clients.jedis.BuilderFactory;
15-
import redis.clients.jedis.util.DoublePrecision;
1614
import redis.clients.jedis.util.KeyValue;
17-
import redis.clients.jedis.util.SafeEncoder;
1815

1916
public final class SearchBuilderFactory {
2017

21-
public static final Builder<Map<String, Object>> SEARCH_PROFILE_PROFILE = new Builder<Map<String, Object>>() {
22-
23-
private final String ITERATORS_PROFILE_STR = "Iterators profile";
24-
private final String CHILD_ITERATORS_STR = "Child iterators";
25-
private final String RESULT_PROCESSORS_PROFILE_STR = "Result processors profile";
26-
27-
@Override
28-
public Map<String, Object> build(Object data) {
29-
List<Object> list = (List<Object>) SafeEncoder.encodeObject(data);
30-
Map<String, Object> profileMap = new HashMap<>(list.size(), 1f);
31-
32-
for (Object listObject : list) {
33-
List<Object> attributeList = (List<Object>) listObject;
34-
String attributeName = (String) attributeList.get(0);
35-
Object attributeValue;
36-
37-
if (attributeList.size() == 2) {
38-
39-
Object value = attributeList.get(1);
40-
if (attributeName.equals(ITERATORS_PROFILE_STR)) {
41-
attributeValue = parseIterators(value);
42-
} else if (attributeName.endsWith(" time")) {
43-
attributeValue = DoublePrecision.parseEncodedFloatingPointNumber(value);
44-
} else {
45-
attributeValue = value;
46-
}
47-
48-
} else if (attributeList.size() > 2) {
49-
50-
if (attributeName.equals(RESULT_PROCESSORS_PROFILE_STR)) {
51-
List<Map<String, Object>> resultProcessorsProfileList = new ArrayList<>(attributeList.size() - 1);
52-
for (int i = 1; i < attributeList.size(); i++) {
53-
resultProcessorsProfileList.add(parseResultProcessors(attributeList.get(i)));
54-
}
55-
attributeValue = resultProcessorsProfileList;
56-
} else {
57-
attributeValue = attributeList.subList(1, attributeList.size());
58-
}
59-
60-
} else {
61-
attributeValue = null;
62-
}
63-
64-
profileMap.put(attributeName, attributeValue);
65-
}
66-
return profileMap;
67-
}
68-
69-
private Map<String, Object> parseResultProcessors(Object data) {
70-
List<Object> list = (List<Object>) data;
71-
Map<String, Object> map = new HashMap<>(list.size() / 2, 1f);
72-
for (int i = 0; i < list.size(); i += 2) {
73-
String key = (String) list.get(i);
74-
Object value = list.get(i + 1);
75-
if (key.equals("Time")) {
76-
value = DoublePrecision.parseEncodedFloatingPointNumber(value);
77-
}
78-
map.put(key, value);
79-
}
80-
return map;
81-
}
82-
83-
private Object parseIterators(Object data) {
84-
if (!(data instanceof List)) return data;
85-
List iteratorsAttributeList = (List) data;
86-
int childIteratorsIndex = iteratorsAttributeList.indexOf(CHILD_ITERATORS_STR);
87-
// https://github.com/RediSearch/RediSearch/issues/3205 patch. TODO: Undo if resolved in RediSearch.
88-
if (childIteratorsIndex < 0) childIteratorsIndex = iteratorsAttributeList.indexOf("Child iterator");
89-
90-
Map<String, Object> iteratorsProfile;
91-
if (childIteratorsIndex < 0) {
92-
childIteratorsIndex = iteratorsAttributeList.size();
93-
iteratorsProfile = new HashMap<>(childIteratorsIndex / 2, 1f);
94-
} else {
95-
iteratorsProfile = new HashMap<>(1 + childIteratorsIndex / 2, 1f);
96-
}
97-
98-
for (int i = 0; i < childIteratorsIndex; i += 2) {
99-
String key = (String) iteratorsAttributeList.get(i);
100-
Object value = iteratorsAttributeList.get(i + 1);
101-
if (key.equals("Time")) {
102-
value = DoublePrecision.parseEncodedFloatingPointNumber(value);
103-
}
104-
iteratorsProfile.put(key, value);
105-
}
106-
107-
if (childIteratorsIndex + 1 < iteratorsAttributeList.size()) {
108-
List childIteratorsList = new ArrayList(iteratorsAttributeList.size() - childIteratorsIndex - 1);
109-
for (int i = childIteratorsIndex + 1; i < iteratorsAttributeList.size(); i++) {
110-
childIteratorsList.add(parseIterators(iteratorsAttributeList.get(i)));
111-
}
112-
iteratorsProfile.put(CHILD_ITERATORS_STR, childIteratorsList);
113-
}
114-
return iteratorsProfile;
115-
}
116-
};
117-
11818
public static final Builder<Map<String, List<String>>> SEARCH_SYNONYM_GROUPS = new Builder<Map<String, List<String>>>() {
11919
@Override
12020
public Map<String, List<String>> build(Object data) {

src/test/java/io/redis/test/utils/RedisVersion.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
package io.redis.test.utils;
22

3-
public class RedisVersion implements Comparable<RedisVersion>{
3+
public class RedisVersion implements Comparable<RedisVersion> {
44
public static final RedisVersion V6_0_0 = RedisVersion.of("6.0.0");
55
public static final RedisVersion V7_0_0 = RedisVersion.of("7.0.0");
66
public static final RedisVersion V7_2_0 = RedisVersion.of("7.2.0");
77
public static final RedisVersion V7_4 = RedisVersion.of("7.4");
8+
public static final RedisVersion V8_0_0_PRE = RedisVersion.of("7.9.0");
89
public static final RedisVersion V8_0_0 = RedisVersion.of("8.0.0");
910

1011
private final int major;

src/test/java/redis/clients/jedis/mocked/MockedCommandObjectsTestBase.java

+5-20
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,11 @@
1212
import redis.clients.jedis.GeoCoordinate;
1313
import redis.clients.jedis.StreamEntryID;
1414
import redis.clients.jedis.graph.ResultSet;
15-
import redis.clients.jedis.resps.FunctionStats;
16-
import redis.clients.jedis.resps.GeoRadiusResponse;
17-
import redis.clients.jedis.resps.LCSMatchResult;
18-
import redis.clients.jedis.resps.LibraryInfo;
19-
import redis.clients.jedis.resps.ScanResult;
20-
import redis.clients.jedis.resps.StreamConsumerInfo;
21-
import redis.clients.jedis.resps.StreamConsumersInfo;
22-
import redis.clients.jedis.resps.StreamEntry;
23-
import redis.clients.jedis.resps.StreamFullInfo;
24-
import redis.clients.jedis.resps.StreamGroupInfo;
25-
import redis.clients.jedis.resps.StreamInfo;
26-
import redis.clients.jedis.resps.StreamPendingEntry;
27-
import redis.clients.jedis.resps.StreamPendingSummary;
28-
import redis.clients.jedis.resps.Tuple;
15+
import redis.clients.jedis.resps.*;
16+
import redis.clients.jedis.search.ProfilingInfo;
2917
import redis.clients.jedis.search.SearchResult;
3018
import redis.clients.jedis.search.aggr.AggregationResult;
31-
import redis.clients.jedis.timeseries.TSElement;
32-
import redis.clients.jedis.timeseries.TSInfo;
33-
import redis.clients.jedis.timeseries.TSMGetElement;
34-
import redis.clients.jedis.timeseries.TSMRangeElements;
19+
import redis.clients.jedis.timeseries.*;
3520
import redis.clients.jedis.util.KeyValue;
3621

3722
/**
@@ -99,9 +84,9 @@ public final static class MyBean {
9984
@Mock protected CommandObject<List<Tuple>> listTupleCommandObject;
10085
@Mock protected CommandObject<List<byte[]>> listBytesCommandObject;
10186
@Mock protected CommandObject<Long> longCommandObject;
102-
@Mock protected CommandObject<Map.Entry<AggregationResult, Map<String, Object>>> entryAggregationResultMapStringObjectCommandObject;
87+
@Mock protected CommandObject<Map.Entry<AggregationResult, ProfilingInfo>> entryAggregationResultMapStringObjectCommandObject;
10388
@Mock protected CommandObject<Map.Entry<Long, byte[]>> entryLongBytesCommandObject;
104-
@Mock protected CommandObject<Map.Entry<SearchResult, Map<String, Object>>> entrySearchResultMapStringObjectCommandObject;
89+
@Mock protected CommandObject<Map.Entry<SearchResult, ProfilingInfo>> entrySearchResultMapStringObjectCommandObject;
10590
@Mock protected CommandObject<Map.Entry<StreamEntryID, List<StreamEntry>>> entryStreamEntryIdListStreamEntryCommandObject;
10691
@Mock protected CommandObject<Map.Entry<StreamEntryID, List<StreamEntryID>>> entryStreamEntryIdListStreamEntryIdCommandObject;
10792
@Mock protected CommandObject<Map<String, List<String>>> mapStringListStringCommandObject;

0 commit comments

Comments
 (0)