Skip to content

Commit

Permalink
Deprecate the STRALGO command and implement the LCS in its place (#3037)
Browse files Browse the repository at this point in the history
* Deprecate the STRALGO command and implement the LCS in its place

* Polishing

---------

Co-authored-by: Tihomir Mateev <[email protected]>
  • Loading branch information
Dltmd202 and tishun authored Dec 1, 2024
1 parent be87576 commit 5c211ae
Show file tree
Hide file tree
Showing 17 changed files with 374 additions and 90 deletions.
5 changes: 5 additions & 0 deletions src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -2412,6 +2412,11 @@ public RedisFuture<StringMatchResult> stralgoLcs(StrAlgoArgs args) {
return dispatch(commandBuilder.stralgoLcs(args));
}

@Override
public RedisFuture<StringMatchResult> lcs(LcsArgs args) {
return dispatch(commandBuilder.lcs(args));
}

@Override
public RedisFuture<Set<V>> sunion(K... keys) {
return dispatch(commandBuilder.sunion(keys));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2495,6 +2495,11 @@ public Mono<StringMatchResult> stralgoLcs(StrAlgoArgs strAlgoArgs) {
return createMono(() -> commandBuilder.stralgoLcs(strAlgoArgs));
}

@Override
public Mono<StringMatchResult> lcs(LcsArgs lcsArgs) {
return createMono(() -> commandBuilder.lcs(lcsArgs));
}

@Override
public Flux<V> sunion(K... keys) {
return createDissolvingFlux(() -> commandBuilder.sunion(keys));
Expand Down
130 changes: 130 additions & 0 deletions src/main/java/io/lettuce/core/LcsArgs.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
* Copyright 2011-Present, Redis Ltd. and Contributors
* All rights reserved.
*
* Licensed under the MIT License.
*/
package io.lettuce.core;

import io.lettuce.core.internal.LettuceAssert;
import io.lettuce.core.protocol.CommandArgs;
import io.lettuce.core.protocol.CommandKeyword;

/**
* Argument list builder for the Redis <a href="https://redis.io/commands/lcs">LCS</a> command. Static import the methods from
* {@link LcsArgs.Builder} and call the methods: {@code keys(…)} .
* <p>
* {@link LcsArgs} is a mutable object and instances should be used only once to avoid shared mutable state.
*
* @author Seonghwan Lee
* @since 6.6
* @see <a href="https://redis.io/commands/lcs">LCS command refference</a>
*/
public class LcsArgs implements CompositeArgument {

private boolean justLen;

private int minMatchLen;

private boolean withMatchLen;

private boolean withIdx;

private String[] keys;

/**
* Builder entry points for {@link LcsArgs}.
*/
public static class Builder {

/**
* Utility constructor.
*/
private Builder() {
}

/**
* Creates new {@link LcsArgs} by keys.
*
* @return new {@link LcsArgs} with {@literal By KEYS} set.
*/
public static LcsArgs keys(String... keys) {
return new LcsArgs().by(keys);
}

}

/**
* restrict the list of matches to the ones of a given minimal length.
*
* @return {@code this} {@link LcsArgs}.
*/
public LcsArgs minMatchLen(int minMatchLen) {
this.minMatchLen = minMatchLen;
return this;
}

/**
* Request just the length of the match for results.
*
* @return {@code this} {@link LcsArgs}.
*/
public LcsArgs justLen() {
justLen = true;
return this;
}

/**
* Request match len for results.
*
* @return {@code this} {@link LcsArgs}.
*/
public LcsArgs withMatchLen() {
withMatchLen = true;
return this;
}

/**
* Request match position in each string for results.
*
* @return {@code this} {@link LcsArgs}.
*/
public LcsArgs withIdx() {
withIdx = true;
return this;
}

public LcsArgs by(String... keys) {
LettuceAssert.notEmpty(keys, "Keys must not be empty");

this.keys = keys;
return this;
}

public boolean isWithIdx() {
return withIdx;
}

@Override
public <K, V> void build(CommandArgs<K, V> args) {
for (String key : keys) {
args.add(key);
}
if (justLen) {
args.add(CommandKeyword.LEN);
}
if (withIdx) {
args.add(CommandKeyword.IDX);
}

if (minMatchLen > 0) {
args.add(CommandKeyword.MINMATCHLEN);
args.add(minMatchLen);
}

if (withMatchLen) {
args.add(CommandKeyword.WITHMATCHLEN);
}
}

}
9 changes: 9 additions & 0 deletions src/main/java/io/lettuce/core/RedisCommandBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
* @author Mikhael Sokolov
* @author Tihomir Mateev
* @author Ali Takavci
* @author Seonghwan Lee
*/
@SuppressWarnings({ "unchecked", "varargs" })
class RedisCommandBuilder<K, V> extends BaseRedisCommandBuilder<K, V> {
Expand Down Expand Up @@ -2912,6 +2913,14 @@ Command<K, V, StringMatchResult> stralgoLcs(StrAlgoArgs strAlgoArgs) {
return createCommand(STRALGO, new StringMatchResultOutput<>(codec), args);
}

Command<K, V, StringMatchResult> lcs(LcsArgs lcsArgs) {
LettuceAssert.notNull(lcsArgs, "lcsArgs" + MUST_NOT_BE_NULL);

CommandArgs<K, V> args = new CommandArgs<>(codec);
lcsArgs.build(args);
return createCommand(LCS, new StringMatchResultOutput<>(codec), args);
}

Command<K, V, Set<V>> sunion(K... keys) {
notEmpty(keys);

Expand Down
3 changes: 3 additions & 0 deletions src/main/java/io/lettuce/core/StrAlgoArgs.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@
* {@link StrAlgoArgs} is a mutable object and instances should be used only once to avoid shared mutable state.
*
* @author dengliming
* @deprecated As of 6.6 in favor of {@link LcsArgs}
* @see <a href="https://redis.io/commands/lcs">LCS command refference</a>
* @since 6.0
*/
@Deprecated
public class StrAlgoArgs implements CompositeArgument {

private boolean justLen;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import io.lettuce.core.KeyValue;
import io.lettuce.core.RedisFuture;
import io.lettuce.core.SetArgs;
import io.lettuce.core.LcsArgs;
import io.lettuce.core.StrAlgoArgs;
import io.lettuce.core.StringMatchResult;
import io.lettuce.core.output.KeyValueStreamingChannel;
Expand Down Expand Up @@ -410,6 +411,8 @@ public interface RedisStringAsyncCommands<K, V> {
/**
* The STRALGO command implements complex algorithms that operate on strings. This method uses the LCS algorithm (longest
* common substring).
* <p>
* Command is no longer available in Redis server versions 7.0.x and later.
*
* <ul>
* <li>Without modifiers the string representing the longest common substring is returned.</li>
Expand All @@ -422,10 +425,30 @@ public interface RedisStringAsyncCommands<K, V> {
*
* @param strAlgoArgs command arguments.
* @return StringMatchResult.
* @deprecated since 6.6 in favor of {@link #lcs(LcsArgs)}.
* @since 6.0
*/
@Deprecated
RedisFuture<StringMatchResult> stralgoLcs(StrAlgoArgs strAlgoArgs);

/**
* The LCS command implements the longest common subsequence algorithm.
*
* <ul>
* <li>Without modifiers, the string representing the longest common substring is returned.</li>
* <li>When {@link LcsArgs#justLen() LEN} is given the command returns the length of the longest common substring.</li>
* <li>When {@link LcsArgs#withIdx() IDX} is given the command returns an array with the LCS length and all the ranges in
* both the strings, start and end offset for each string, where there are matches. When {@link LcsArgs#withMatchLen()
* WITHMATCHLEN} is given each array representing a match will also have the length of the match.</li>
* </ul>
*
* @param lcsArgs command arguments supplied by the {@link LcsArgs}.
* @return StringMatchResult
* @see <a href="https://redis.io/commands/lcs">LCS command refference</a>
* @since 6.6
*/
RedisFuture<StringMatchResult> lcs(LcsArgs lcsArgs);

/**
* Get the length of the value stored in a key.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import io.lettuce.core.KeyValue;
import io.lettuce.core.SetArgs;
import io.lettuce.core.StrAlgoArgs;
import io.lettuce.core.LcsArgs;
import io.lettuce.core.StringMatchResult;
import io.lettuce.core.Value;
import io.lettuce.core.output.KeyValueStreamingChannel;
Expand Down Expand Up @@ -414,6 +415,8 @@ public interface RedisStringReactiveCommands<K, V> {
/**
* The STRALGO command implements complex algorithms that operate on strings. This method uses the LCS algorithm (longest
* common substring).
* <p>
* Command is no longer available in Redis server versions 7.0.x and later.
*
* <ul>
* <li>Without modifiers the string representing the longest common substring is returned.</li>
Expand All @@ -426,10 +429,30 @@ public interface RedisStringReactiveCommands<K, V> {
*
* @param strAlgoArgs command arguments.
* @return StringMatchResult.
* @deprecated since 6.6 in favor of {@link #lcs(LcsArgs)}.
* @since 6.0
*/
@Deprecated
Mono<StringMatchResult> stralgoLcs(StrAlgoArgs strAlgoArgs);

/**
* The LCS command implements the longest common subsequence algorithm.
*
* <ul>
* <li>Without modifiers, the string representing the longest common substring is returned.</li>
* <li>When {@link LcsArgs#justLen() LEN} is given the command returns the length of the longest common substring.</li>
* <li>When {@link LcsArgs#withIdx() IDX} is given the command returns an array with the LCS length and all the ranges in
* both the strings, start and end offset for each string, where there are matches. When {@link LcsArgs#withMatchLen()
* WITHMATCHLEN} is given each array representing a match will also have the length of the match.</li>
* </ul>
*
* @param lcsArgs command arguments supplied by the {@link LcsArgs}.
* @return StringMatchResult
* @see <a href="https://redis.io/commands/lcs">LCS command refference</a>
* @since 6.6
*/
Mono<StringMatchResult> lcs(LcsArgs lcsArgs);

/**
* Get the length of the value stored in a key.
*
Expand Down
23 changes: 23 additions & 0 deletions src/main/java/io/lettuce/core/api/sync/RedisStringCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import io.lettuce.core.KeyValue;
import io.lettuce.core.SetArgs;
import io.lettuce.core.StrAlgoArgs;
import io.lettuce.core.LcsArgs;
import io.lettuce.core.StringMatchResult;
import io.lettuce.core.output.KeyValueStreamingChannel;

Expand Down Expand Up @@ -409,6 +410,8 @@ public interface RedisStringCommands<K, V> {
/**
* The STRALGO command implements complex algorithms that operate on strings. This method uses the LCS algorithm (longest
* common substring).
* <p>
* Command is no longer available in Redis server versions 7.0.x and later.
*
* <ul>
* <li>Without modifiers the string representing the longest common substring is returned.</li>
Expand All @@ -421,10 +424,30 @@ public interface RedisStringCommands<K, V> {
*
* @param strAlgoArgs command arguments.
* @return StringMatchResult.
* @deprecated since 6.6 in favor of {@link #lcs(LcsArgs)}.
* @since 6.0
*/
@Deprecated
StringMatchResult stralgoLcs(StrAlgoArgs strAlgoArgs);

/**
* The LCS command implements the longest common subsequence algorithm.
*
* <ul>
* <li>Without modifiers, the string representing the longest common substring is returned.</li>
* <li>When {@link LcsArgs#justLen() LEN} is given the command returns the length of the longest common substring.</li>
* <li>When {@link LcsArgs#withIdx() IDX} is given the command returns an array with the LCS length and all the ranges in
* both the strings, start and end offset for each string, where there are matches. When {@link LcsArgs#withMatchLen()
* WITHMATCHLEN} is given each array representing a match will also have the length of the match.</li>
* </ul>
*
* @param lcsArgs command arguments supplied by the {@link LcsArgs}.
* @return StringMatchResult
* @see <a href="https://redis.io/commands/lcs">LCS command refference</a>
* @since 6.6
*/
StringMatchResult lcs(LcsArgs lcsArgs);

/**
* Get the length of the value stored in a key.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import io.lettuce.core.SetArgs;
import io.lettuce.core.StrAlgoArgs;
import io.lettuce.core.StringMatchResult;
import io.lettuce.core.LcsArgs;
import io.lettuce.core.output.KeyValueStreamingChannel;

/**
Expand Down Expand Up @@ -409,6 +410,8 @@ public interface NodeSelectionStringAsyncCommands<K, V> {
/**
* The STRALGO command implements complex algorithms that operate on strings. This method uses the LCS algorithm (longest
* common substring).
* <p>
* Command is no longer available in Redis server versions 7.0.x and later.
*
* <ul>
* <li>Without modifiers the string representing the longest common substring is returned.</li>
Expand All @@ -421,10 +424,30 @@ public interface NodeSelectionStringAsyncCommands<K, V> {
*
* @param strAlgoArgs command arguments.
* @return StringMatchResult.
* @deprecated since 6.6 in favor of {@link #lcs(LcsArgs)}.
* @since 6.0
*/
@Deprecated
AsyncExecutions<StringMatchResult> stralgoLcs(StrAlgoArgs strAlgoArgs);

/**
* The LCS command implements the longest common subsequence algorithm.
*
* <ul>
* <li>Without modifiers, the string representing the longest common substring is returned.</li>
* <li>When {@link LcsArgs#justLen() LEN} is given the command returns the length of the longest common substring.</li>
* <li>When {@link LcsArgs#withIdx() IDX} is given the command returns an array with the LCS length and all the ranges in
* both the strings, start and end offset for each string, where there are matches. When {@link LcsArgs#withMatchLen()
* WITHMATCHLEN} is given each array representing a match will also have the length of the match.</li>
* </ul>
*
* @param lcsArgs command arguments supplied by the {@link LcsArgs}.
* @return StringMatchResult
* @see <a href="https://redis.io/commands/lcs">LCS command refference</a>
* @since 6.6
*/
AsyncExecutions<StringMatchResult> lcs(LcsArgs lcsArgs);

/**
* Get the length of the value stored in a key.
*
Expand Down
Loading

0 comments on commit 5c211ae

Please sign in to comment.