Skip to content

Commit

Permalink
Merge branch 'master' into graph-complete-remove
Browse files Browse the repository at this point in the history
  • Loading branch information
sazzad16 committed Jan 30, 2025
2 parents c3eae13 + cd9346a commit 6bc27eb
Show file tree
Hide file tree
Showing 11 changed files with 144 additions and 367 deletions.
49 changes: 34 additions & 15 deletions src/main/java/redis/clients/jedis/CommandObjects.java
Original file line number Diff line number Diff line change
Expand Up @@ -3433,7 +3433,7 @@ public final CommandObject<String> ftCursorDel(String indexName, long cursorId)
.key(indexName).add(cursorId), BuilderFactory.STRING);
}

public final CommandObject<Map.Entry<AggregationResult, Map<String, Object>>> ftProfileAggregate(
public final CommandObject<Map.Entry<AggregationResult, ProfilingInfo>> ftProfileAggregate(
String indexName, FTProfileParams profileParams, AggregationBuilder aggr) {
return new CommandObject<>(checkAndRoundRobinSearchCommand(SearchCommand.PROFILE, indexName)
.add(SearchKeyword.AGGREGATE).addParams(profileParams).add(SearchKeyword.QUERY)
Expand All @@ -3442,7 +3442,7 @@ public final CommandObject<Map.Entry<AggregationResult, Map<String, Object>>> ft
: AggregationResult.SEARCH_AGGREGATION_RESULT_WITH_CURSOR));
}

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

public final CommandObject<Map.Entry<SearchResult, Map<String, Object>>> ftProfileSearch(
public final CommandObject<Map.Entry<SearchResult, ProfilingInfo>> ftProfileSearch(
String indexName, FTProfileParams profileParams, String query, FTSearchParams searchParams) {
return new CommandObject<>(checkAndRoundRobinSearchCommand(SearchCommand.PROFILE, indexName)
.add(SearchKeyword.SEARCH).addParams(profileParams).add(SearchKeyword.QUERY).add(query)
Expand Down Expand Up @@ -4428,32 +4428,51 @@ public void setDefaultSearchDialect(int dialect) {
this.searchDialect.set(dialect);
}

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

private static final String PROFILE_STR = "profile";
private static final String PROFILE_STR_REDIS7 = "profile";
private static final String PROFILE_STR_REDIS8 = "Profile";
private static final String RESULTS_STR_REDIS7 = "results";
private static final String RESULTS_STR_REDIS8 = "Results";

private final Builder<T> replyBuilder;
private final Builder<T> resultsBuilder;

public SearchProfileResponseBuilder(Builder<T> replyBuilder) {
this.replyBuilder = replyBuilder;
public SearchProfileResponseBuilder(Builder<T> resultsBuilder) {
this.resultsBuilder = resultsBuilder;
}

@Override
public Map.Entry<T, Map<String, Object>> build(Object data) {
public Map.Entry<T, ProfilingInfo> build(Object data) {
List list = (List) data;
if (list == null || list.isEmpty()) return null;

if (list.get(0) instanceof KeyValue) {
if (list.get(0) instanceof KeyValue) { // RESP3
Object resultsData = null, profileData = null;

for (KeyValue keyValue : (List<KeyValue>) data) {
if (PROFILE_STR.equals(BuilderFactory.STRING.build(keyValue.getKey()))) {
return KeyValue.of(replyBuilder.build(data),
BuilderFactory.AGGRESSIVE_ENCODED_OBJECT_MAP.build(keyValue.getValue()));
String keyStr = BuilderFactory.STRING.build(keyValue.getKey());
switch (keyStr) {
case PROFILE_STR_REDIS7:
case PROFILE_STR_REDIS8:
profileData = keyValue.getValue();
break;
case RESULTS_STR_REDIS7:
resultsData = data;
break;
case RESULTS_STR_REDIS8:
resultsData = keyValue.getValue();
break;
}
}

assert resultsData != null : "Could not detect Results data.";
assert profileData != null : "Could not detect Profile data.";
return KeyValue.of(resultsBuilder.build(resultsData),
ProfilingInfo.PROFILING_INFO_BUILDER.build(profileData));
}

return KeyValue.of(replyBuilder.build(list.get(0)),
SearchBuilderFactory.SEARCH_PROFILE_PROFILE.build(list.get(1)));
return KeyValue.of(resultsBuilder.build(list.get(0)),
ProfilingInfo.PROFILING_INFO_BUILDER.build(list.get(1)));
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/main/java/redis/clients/jedis/UnifiedJedis.java
Original file line number Diff line number Diff line change
Expand Up @@ -3979,19 +3979,19 @@ public FtAggregateIteration ftAggregateIteration(String indexName, AggregationBu
}

@Override
public Map.Entry<AggregationResult, Map<String, Object>> ftProfileAggregate(String indexName,
public Map.Entry<AggregationResult, ProfilingInfo> ftProfileAggregate(String indexName,
FTProfileParams profileParams, AggregationBuilder aggr) {
return executeCommand(commandObjects.ftProfileAggregate(indexName, profileParams, aggr));
}

@Override
public Map.Entry<SearchResult, Map<String, Object>> ftProfileSearch(String indexName,
public Map.Entry<SearchResult, ProfilingInfo> ftProfileSearch(String indexName,
FTProfileParams profileParams, Query query) {
return executeCommand(commandObjects.ftProfileSearch(indexName, profileParams, query));
}

@Override
public Map.Entry<SearchResult, Map<String, Object>> ftProfileSearch(String indexName,
public Map.Entry<SearchResult, ProfilingInfo> ftProfileSearch(String indexName,
FTProfileParams profileParams, String query, FTSearchParams searchParams) {
return executeCommand(commandObjects.ftProfileSearch(indexName, profileParams, query, searchParams));
}
Expand Down
31 changes: 31 additions & 0 deletions src/main/java/redis/clients/jedis/search/ProfilingInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package redis.clients.jedis.search;

import static redis.clients.jedis.BuilderFactory.AGGRESSIVE_ENCODED_OBJECT;

import redis.clients.jedis.Builder;

public class ProfilingInfo {

private final Object profilingInfo;

private ProfilingInfo(Object profilingInfo) {
this.profilingInfo = profilingInfo;
}

public Object getProfilingInfo() {
return profilingInfo;
}

@Override
public String toString() {
return String.valueOf(profilingInfo);
}

public static final Builder<ProfilingInfo> PROFILING_INFO_BUILDER
= new Builder<ProfilingInfo>() {
@Override
public ProfilingInfo build(Object data) {
return new ProfilingInfo(AGGRESSIVE_ENCODED_OBJECT.build(data));
}
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,13 @@ default SearchResult ftSearch(String indexName) {

String ftCursorDel(String indexName, long cursorId);

Map.Entry<AggregationResult, Map<String, Object>> ftProfileAggregate(String indexName,
Map.Entry<AggregationResult, ProfilingInfo> ftProfileAggregate(String indexName,
FTProfileParams profileParams, AggregationBuilder aggr);

Map.Entry<SearchResult, Map<String, Object>> ftProfileSearch(String indexName,
Map.Entry<SearchResult, ProfilingInfo> ftProfileSearch(String indexName,
FTProfileParams profileParams, Query query);

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

String ftSynUpdate(String indexName, String synonymGroupId, String... terms);
Expand Down
100 changes: 0 additions & 100 deletions src/main/java/redis/clients/jedis/search/SearchBuilderFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

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

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
Expand All @@ -12,109 +11,10 @@

import redis.clients.jedis.Builder;
import redis.clients.jedis.BuilderFactory;
import redis.clients.jedis.util.DoublePrecision;
import redis.clients.jedis.util.KeyValue;
import redis.clients.jedis.util.SafeEncoder;

public final class SearchBuilderFactory {

public static final Builder<Map<String, Object>> SEARCH_PROFILE_PROFILE = new Builder<Map<String, Object>>() {

private final String ITERATORS_PROFILE_STR = "Iterators profile";
private final String CHILD_ITERATORS_STR = "Child iterators";
private final String RESULT_PROCESSORS_PROFILE_STR = "Result processors profile";

@Override
public Map<String, Object> build(Object data) {
List<Object> list = (List<Object>) SafeEncoder.encodeObject(data);
Map<String, Object> profileMap = new HashMap<>(list.size(), 1f);

for (Object listObject : list) {
List<Object> attributeList = (List<Object>) listObject;
String attributeName = (String) attributeList.get(0);
Object attributeValue;

if (attributeList.size() == 2) {

Object value = attributeList.get(1);
if (attributeName.equals(ITERATORS_PROFILE_STR)) {
attributeValue = parseIterators(value);
} else if (attributeName.endsWith(" time")) {
attributeValue = DoublePrecision.parseEncodedFloatingPointNumber(value);
} else {
attributeValue = value;
}

} else if (attributeList.size() > 2) {

if (attributeName.equals(RESULT_PROCESSORS_PROFILE_STR)) {
List<Map<String, Object>> resultProcessorsProfileList = new ArrayList<>(attributeList.size() - 1);
for (int i = 1; i < attributeList.size(); i++) {
resultProcessorsProfileList.add(parseResultProcessors(attributeList.get(i)));
}
attributeValue = resultProcessorsProfileList;
} else {
attributeValue = attributeList.subList(1, attributeList.size());
}

} else {
attributeValue = null;
}

profileMap.put(attributeName, attributeValue);
}
return profileMap;
}

private Map<String, Object> parseResultProcessors(Object data) {
List<Object> list = (List<Object>) data;
Map<String, Object> map = new HashMap<>(list.size() / 2, 1f);
for (int i = 0; i < list.size(); i += 2) {
String key = (String) list.get(i);
Object value = list.get(i + 1);
if (key.equals("Time")) {
value = DoublePrecision.parseEncodedFloatingPointNumber(value);
}
map.put(key, value);
}
return map;
}

private Object parseIterators(Object data) {
if (!(data instanceof List)) return data;
List iteratorsAttributeList = (List) data;
int childIteratorsIndex = iteratorsAttributeList.indexOf(CHILD_ITERATORS_STR);
// https://github.com/RediSearch/RediSearch/issues/3205 patch. TODO: Undo if resolved in RediSearch.
if (childIteratorsIndex < 0) childIteratorsIndex = iteratorsAttributeList.indexOf("Child iterator");

Map<String, Object> iteratorsProfile;
if (childIteratorsIndex < 0) {
childIteratorsIndex = iteratorsAttributeList.size();
iteratorsProfile = new HashMap<>(childIteratorsIndex / 2, 1f);
} else {
iteratorsProfile = new HashMap<>(1 + childIteratorsIndex / 2, 1f);
}

for (int i = 0; i < childIteratorsIndex; i += 2) {
String key = (String) iteratorsAttributeList.get(i);
Object value = iteratorsAttributeList.get(i + 1);
if (key.equals("Time")) {
value = DoublePrecision.parseEncodedFloatingPointNumber(value);
}
iteratorsProfile.put(key, value);
}

if (childIteratorsIndex + 1 < iteratorsAttributeList.size()) {
List childIteratorsList = new ArrayList(iteratorsAttributeList.size() - childIteratorsIndex - 1);
for (int i = childIteratorsIndex + 1; i < iteratorsAttributeList.size(); i++) {
childIteratorsList.add(parseIterators(iteratorsAttributeList.get(i)));
}
iteratorsProfile.put(CHILD_ITERATORS_STR, childIteratorsList);
}
return iteratorsProfile;
}
};

public static final Builder<Map<String, List<String>>> SEARCH_SYNONYM_GROUPS = new Builder<Map<String, List<String>>>() {
@Override
public Map<String, List<String>> build(Object data) {
Expand Down
3 changes: 2 additions & 1 deletion src/test/java/io/redis/test/utils/RedisVersion.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package io.redis.test.utils;

public class RedisVersion implements Comparable<RedisVersion>{
public class RedisVersion implements Comparable<RedisVersion> {
public static final RedisVersion V6_0_0 = RedisVersion.of("6.0.0");
public static final RedisVersion V7_0_0 = RedisVersion.of("7.0.0");
public static final RedisVersion V7_2_0 = RedisVersion.of("7.2.0");
public static final RedisVersion V7_4 = RedisVersion.of("7.4");
public static final RedisVersion V8_0_0_PRE = RedisVersion.of("7.9.0");
public static final RedisVersion V8_0_0 = RedisVersion.of("8.0.0");

private final int major;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,10 @@
import redis.clients.jedis.GeoCoordinate;
import redis.clients.jedis.StreamEntryID;
import redis.clients.jedis.resps.*;
import redis.clients.jedis.search.ProfilingInfo;
import redis.clients.jedis.search.SearchResult;
import redis.clients.jedis.search.aggr.AggregationResult;
import redis.clients.jedis.timeseries.TSElement;
import redis.clients.jedis.timeseries.TSInfo;
import redis.clients.jedis.timeseries.TSMGetElement;
import redis.clients.jedis.timeseries.TSMRangeElements;
import redis.clients.jedis.timeseries.*;
import redis.clients.jedis.util.KeyValue;

/**
Expand Down Expand Up @@ -85,9 +83,9 @@ public final static class MyBean {
@Mock protected CommandObject<List<Tuple>> listTupleCommandObject;
@Mock protected CommandObject<List<byte[]>> listBytesCommandObject;
@Mock protected CommandObject<Long> longCommandObject;
@Mock protected CommandObject<Map.Entry<AggregationResult, Map<String, Object>>> entryAggregationResultMapStringObjectCommandObject;
@Mock protected CommandObject<Map.Entry<AggregationResult, ProfilingInfo>> entryAggregationResultMapStringObjectCommandObject;
@Mock protected CommandObject<Map.Entry<Long, byte[]>> entryLongBytesCommandObject;
@Mock protected CommandObject<Map.Entry<SearchResult, Map<String, Object>>> entrySearchResultMapStringObjectCommandObject;
@Mock protected CommandObject<Map.Entry<SearchResult, ProfilingInfo>> entrySearchResultMapStringObjectCommandObject;
@Mock protected CommandObject<Map.Entry<StreamEntryID, List<StreamEntry>>> entryStreamEntryIdListStreamEntryCommandObject;
@Mock protected CommandObject<Map.Entry<StreamEntryID, List<StreamEntryID>>> entryStreamEntryIdListStreamEntryIdCommandObject;
@Mock protected CommandObject<Map<String, List<String>>> mapStringListStringCommandObject;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,7 @@

import org.junit.Test;
import redis.clients.jedis.resps.Tuple;
import redis.clients.jedis.search.FTCreateParams;
import redis.clients.jedis.search.FTProfileParams;
import redis.clients.jedis.search.FTSearchParams;
import redis.clients.jedis.search.FTSpellCheckParams;
import redis.clients.jedis.search.IndexOptions;
import redis.clients.jedis.search.Query;
import redis.clients.jedis.search.Schema;
import redis.clients.jedis.search.SearchResult;
import redis.clients.jedis.search.*;
import redis.clients.jedis.search.aggr.AggregationBuilder;
import redis.clients.jedis.search.aggr.AggregationResult;
import redis.clients.jedis.search.schemafields.SchemaField;
Expand Down Expand Up @@ -773,13 +766,13 @@ public void testFtProfileAggregate() {
String indexName = "myIndex";
FTProfileParams profileParams = new FTProfileParams();
AggregationBuilder aggr = new AggregationBuilder().groupBy("@field");
Map.Entry<AggregationResult, Map<String, Object>> expectedResponse = new AbstractMap.SimpleEntry<>(
mock(AggregationResult.class), Collections.singletonMap("Profile", "Data"));
Map.Entry<AggregationResult, ProfilingInfo> expectedResponse = new AbstractMap.SimpleEntry<>(
mock(AggregationResult.class), mock(ProfilingInfo.class));

when(commandObjects.ftProfileAggregate(indexName, profileParams, aggr)).thenReturn(entryAggregationResultMapStringObjectCommandObject);
when(commandExecutor.executeCommand(entryAggregationResultMapStringObjectCommandObject)).thenReturn(expectedResponse);

Map.Entry<AggregationResult, Map<String, Object>> result = jedis.ftProfileAggregate(indexName, profileParams, aggr);
Map.Entry<AggregationResult, ProfilingInfo> result = jedis.ftProfileAggregate(indexName, profileParams, aggr);

assertThat(result, equalTo(expectedResponse));

Expand All @@ -792,13 +785,13 @@ public void testFtProfileSearchWithQueryObject() {
String indexName = "myIndex";
FTProfileParams profileParams = new FTProfileParams();
Query query = new Query("hello world").limit(0, 10);
Map.Entry<SearchResult, Map<String, Object>> expectedResponse = new AbstractMap.SimpleEntry<>(
mock(SearchResult.class), Collections.singletonMap("Profile", "Data"));
Map.Entry<SearchResult, ProfilingInfo> expectedResponse = new AbstractMap.SimpleEntry<>(
mock(SearchResult.class), mock(ProfilingInfo.class));

when(commandObjects.ftProfileSearch(indexName, profileParams, query)).thenReturn(entrySearchResultMapStringObjectCommandObject);
when(commandExecutor.executeCommand(entrySearchResultMapStringObjectCommandObject)).thenReturn(expectedResponse);

Map.Entry<SearchResult, Map<String, Object>> result = jedis.ftProfileSearch(indexName, profileParams, query);
Map.Entry<SearchResult, ProfilingInfo> result = jedis.ftProfileSearch(indexName, profileParams, query);

assertThat(result, equalTo(expectedResponse));

Expand All @@ -812,13 +805,13 @@ public void testFtProfileSearchWithQueryAndSearchParams() {
FTProfileParams profileParams = new FTProfileParams();
String query = "hello world";
FTSearchParams searchParams = new FTSearchParams().noContent().limit(0, 10);
Map.Entry<SearchResult, Map<String, Object>> expectedResponse = new AbstractMap.SimpleEntry<>(
mock(SearchResult.class), Collections.singletonMap("Profile", "Data"));
Map.Entry<SearchResult, ProfilingInfo> expectedResponse = new AbstractMap.SimpleEntry<>(
mock(SearchResult.class), mock(ProfilingInfo.class));

when(commandObjects.ftProfileSearch(indexName, profileParams, query, searchParams)).thenReturn(entrySearchResultMapStringObjectCommandObject);
when(commandExecutor.executeCommand(entrySearchResultMapStringObjectCommandObject)).thenReturn(expectedResponse);

Map.Entry<SearchResult, Map<String, Object>> result = jedis.ftProfileSearch(indexName, profileParams, query, searchParams);
Map.Entry<SearchResult, ProfilingInfo> result = jedis.ftProfileSearch(indexName, profileParams, query, searchParams);

assertThat(result, equalTo(expectedResponse));

Expand Down
Loading

0 comments on commit 6bc27eb

Please sign in to comment.