Skip to content

Commit

Permalink
FT.PROFILE.
Browse files Browse the repository at this point in the history
Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com>
  • Loading branch information
Yury-Fridlyand committed Oct 18, 2024
1 parent 87412e8 commit f1e346e
Show file tree
Hide file tree
Showing 5 changed files with 300 additions and 56 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
* Java: Added `FT.DROPINDEX` ([#2440](https://github.com/valkey-io/valkey-glide/pull/2440))
* Java: Added `FT.SEARCH` ([#2439](https://github.com/valkey-io/valkey-glide/pull/2439))
* Java: Added `FT.AGGREGATE` ([#2466](https://github.com/valkey-io/valkey-glide/pull/2466))
* Java: Added `FT.PROFILE` ([#2473](https://github.com/valkey-io/valkey-glide/pull/2473))
* Java: Added `JSON.SET` and `JSON.GET` ([#2462](https://github.com/valkey-io/valkey-glide/pull/2462))
* Core: Update routing for commands from server modules ([#2461](https://github.com/valkey-io/valkey-glide/pull/2461))

Expand Down
51 changes: 48 additions & 3 deletions glide-core/src/client/value_conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub(crate) enum ExpectedReturnType<'a> {
ArrayOfDoubleOrNull,
FTAggregateReturnType,
FTSearchReturnType,
FTProfileReturnType(&'a Option<ExpectedReturnType<'a>>),
Lolwut,
ArrayOfStringAndArrays,
ArrayOfArraysOfDoubleOrNull,
Expand Down Expand Up @@ -938,7 +939,7 @@ pub(crate) fn convert_to_expected_type(
let Value::Array(fields) = aggregation else {
return Err((
ErrorKind::TypeError,
"Response couldn't be converted for FT.AGGREGATION",
"Response couldn't be converted for FT.AGGREGATE",
format!("(`fields` was {:?})", get_value_type(&aggregation)),
)
.into());
Expand All @@ -953,7 +954,7 @@ pub(crate) fn convert_to_expected_type(
}
_ => Err((
ErrorKind::TypeError,
"Response couldn't be converted to FT.AGGREGATION",
"Response couldn't be converted for FT.AGGREGATE",
format!("(response was {:?})", get_value_type(&value)),
)
.into()),
Expand Down Expand Up @@ -999,11 +1000,47 @@ pub(crate) fn convert_to_expected_type(
},
_ => Err((
ErrorKind::TypeError,
"Response couldn't be converted to Pair",
"Response couldn't be converted for FT.SEARCH",
format!("(response was {:?})", get_value_type(&value)),
)
.into())
},
ExpectedReturnType::FTProfileReturnType(type_of_query) => match value {
/*
Example of the response
1) <query response>
2) 1) 1) "parse.time"
2) 119
2) 1) "all.count"
2) 4
3) 1) "sync.time"
2) 0
Converting response to
1) <converted query>
2) 1# "parse.time" => 119
2# "all.count" => 4
3# "sync.time" => 0
Converting first array element as it is needed for the inner query and second element to a map.
*/
Value::Array(mut array) if array.len() == 2 => {
let res = vec![
convert_to_expected_type(array.remove(0), *type_of_query)?,
convert_to_expected_type(array.remove(0), Some(ExpectedReturnType::Map {
key_type: &None,
value_type: &None,
}))?];

Ok(Value::Array(res))
},
_ => Err((
ErrorKind::TypeError,
"Response couldn't be converted for FT.PROFILE",
format!("(response was {:?})", get_value_type(&value)),
)
.into())
}
}
}

Expand Down Expand Up @@ -1370,6 +1407,14 @@ pub(crate) fn expected_type_for_cmd(cmd: &Cmd) -> Option<ExpectedReturnType> {
}),
b"FT.AGGREGATE" => Some(ExpectedReturnType::FTAggregateReturnType),
b"FT.SEARCH" => Some(ExpectedReturnType::FTSearchReturnType),
// TODO replace with tuple
b"FT.PROFILE" => Some(ExpectedReturnType::FTProfileReturnType(
if cmd.arg_idx(2).is_some_and(|a| a == b"SEARCH") {
&Some(ExpectedReturnType::FTSearchReturnType)
} else {
&Some(ExpectedReturnType::FTAggregateReturnType)
},
)),
_ => None,
}
}
Expand Down
32 changes: 32 additions & 0 deletions java/client/src/main/java/glide/api/commands/servermodules/FT.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import glide.api.models.commands.FT.FTAggregateOptions;
import glide.api.models.commands.FT.FTCreateOptions;
import glide.api.models.commands.FT.FTCreateOptions.FieldInfo;
import glide.api.models.commands.FT.FTProfileOptions;
import glide.api.models.commands.FT.FTSearchOptions;
import java.util.Arrays;
import java.util.Map;
Expand Down Expand Up @@ -474,6 +475,37 @@ public static CompletableFuture<Map<GlideString, Object>[]> aggregate(
.thenApply(res -> castArray(res, Map.class));
}

/**
* Runs a search or aggregation query and collects performance profiling information.
*
* @param client The client to execute the command.
* @param indexName The index name.
* @param options Querying and profiling parameters - see {@link FTProfileOptions}.
* @return A two-element array. The first element contains results of query being profiled, the
* second element stores profiling information.
*/
public static CompletableFuture<Object[]> profile(
@NonNull BaseClient client, @NonNull String indexName, @NonNull FTProfileOptions options) {
return profile(client, gs(indexName), options);
}

/**
* Runs a search or aggregation query and collects performance profiling information.
*
* @param client The client to execute the command.
* @param indexName The index name.
* @param options Querying and profiling parameters - see {@link FTProfileOptions}.
* @return A two-element array. The first element contains results of query being profiled, the
* second element stores profiling information.
*/
public static CompletableFuture<Object[]> profile(
@NonNull BaseClient client,
@NonNull GlideString indexName,
@NonNull FTProfileOptions options) {
var args = concatenateArrays(new GlideString[] {gs("FT.PROFILE"), indexName}, options.toArgs());
return executeCommand(client, args, false);
}

/**
* A wrapper for custom command API.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/** Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0 */
package glide.api.models.commands.FT;

import static glide.api.models.GlideString.gs;
import static glide.utils.ArrayTransformUtils.concatenateArrays;

import glide.api.commands.servermodules.FT;
import glide.api.models.GlideString;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

/** Mandatory parameters for {@link FT#profile} command. */
public class FTProfileOptions {
private final QueryType queryType;
private final boolean limited;
private final GlideString[] query;

/** Query type being profiled. */
public enum QueryType {
SEARCH,
AGGREGATE
}

/**
* Profile a query given as an array of module command line arguments.
*
* @param queryType The query type.
* @param commandLine Command arguments (not including index name).
*/
public FTProfileOptions(QueryType queryType, GlideString[] commandLine) {
this(queryType, commandLine, false);
}

/**
* Profile a query given as an array of module command line arguments.
*
* @param queryType The query type.
* @param commandLine Command arguments (not including index name).
*/
public FTProfileOptions(QueryType queryType, String[] commandLine) {
this(queryType, commandLine, false);
}

/**
* Profile a query given as an array of module command line arguments.
*
* @param queryType The query type.
* @param commandLine Command arguments (not including index name).
* @param limited Either provide a full verbose output or some brief version (limited).
*/
public FTProfileOptions(QueryType queryType, GlideString[] commandLine, boolean limited) {
this.queryType = queryType;
this.query = commandLine;
this.limited = limited;
}

/**
* Profile a query given as an array of module command line arguments.
*
* @param queryType The query type.
* @param commandLine Command arguments (not including index name).
* @param limited Either provide a full verbose output or some brief version (limited).
*/
public FTProfileOptions(QueryType queryType, String[] commandLine, boolean limited) {
this(
queryType,
Stream.of(commandLine).map(GlideString::gs).toArray(GlideString[]::new),
limited);
}

/**
* Profile an aggregation query with given parameters.
*
* @param query The query itself.
* @param options {@link FT#aggregate} options.
*/
public FTProfileOptions(String query, FTAggregateOptions options) {
this(gs(query), options);
}

/**
* Profile an aggregation query with given parameters.
*
* @param query The query itself.
* @param options {@link FT#aggregate} options.
*/
public FTProfileOptions(GlideString query, FTAggregateOptions options) {
this(QueryType.AGGREGATE, concatenateArrays(new GlideString[] {query}, options.toArgs()));
}

/**
* Profile a search query with given parameters.
*
* @param query The query itself.
* @param options {@link FT#search} options.
*/
public FTProfileOptions(String query, FTSearchOptions options) {
this(gs(query), options);
}

/**
* Profile a search query with given parameters.
*
* @param query The query itself.
* @param options {@link FT#search} options.
*/
public FTProfileOptions(GlideString query, FTSearchOptions options) {
this(QueryType.SEARCH, concatenateArrays(new GlideString[] {query}, options.toArgs()));
}

/**
* Profile an aggregation query with given parameters.
*
* @param query The query itself.
* @param options {@link FT#aggregate} options.
* @param limited Either provide a full verbose output or some brief version (limited).
*/
public FTProfileOptions(String query, FTAggregateOptions options, boolean limited) {
this(gs(query), options, limited);
}

/**
* Profile a search query with given parameters.
*
* @param query The query itself.
* @param options {@link FT#search} options.
* @param limited Either provide a full verbose output or some brief version (limited).
*/
public FTProfileOptions(GlideString query, FTAggregateOptions options, boolean limited) {
this(
QueryType.AGGREGATE,
concatenateArrays(new GlideString[] {query}, options.toArgs()),
limited);
}

/**
* Profile an aggregation query with given parameters.
*
* @param query The query itself.
* @param options {@link FT#aggregate} options.
* @param limited Either provide a full verbose output or some brief version (limited).
*/
public FTProfileOptions(String query, FTSearchOptions options, boolean limited) {
this(gs(query), options, limited);
}

/**
* Profile a search query with given parameters.
*
* @param query The query itself.
* @param options {@link FT#search} options.
* @param limited Either provide a full verbose output or some brief version (limited).
*/
public FTProfileOptions(GlideString query, FTSearchOptions options, boolean limited) {
this(QueryType.SEARCH, concatenateArrays(new GlideString[] {query}, options.toArgs()), limited);
}

/** Convert to module API. */
public GlideString[] toArgs() {
var args = new ArrayList<GlideString>();
args.add(gs(queryType.toString()));
if (limited) args.add(gs("LIMITED"));
args.add(gs("QUERY"));
args.addAll(List.of(query));
return args.toArray(GlideString[]::new);
}
}
Loading

0 comments on commit f1e346e

Please sign in to comment.