Skip to content

Commit 63ee6b9

Browse files
committed
Deprecate the STRALGO command and implement the LCS in its place
1 parent 114755d commit 63ee6b9

File tree

12 files changed

+282
-63
lines changed

12 files changed

+282
-63
lines changed

src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2414,6 +2414,11 @@ public RedisFuture<StringMatchResult> stralgoLcs(StrAlgoArgs args) {
24142414
return dispatch(commandBuilder.stralgoLcs(args));
24152415
}
24162416

2417+
@Override
2418+
public RedisFuture<StringMatchResult> lcs(LcsArgs args) {
2419+
return dispatch(commandBuilder.lcs(args));
2420+
}
2421+
24172422
@Override
24182423
public RedisFuture<Set<V>> sunion(K... keys) {
24192424
return dispatch(commandBuilder.sunion(keys));

src/main/java/io/lettuce/core/AbstractRedisReactiveCommands.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2499,6 +2499,11 @@ public Mono<StringMatchResult> stralgoLcs(StrAlgoArgs strAlgoArgs) {
24992499
return createMono(() -> commandBuilder.stralgoLcs(strAlgoArgs));
25002500
}
25012501

2502+
@Override
2503+
public Mono<StringMatchResult> lcs(LcsArgs lcsArgs) {
2504+
return createMono(() -> commandBuilder.lcs(lcsArgs));
2505+
}
2506+
25022507
@Override
25032508
public Flux<V> sunion(K... keys) {
25042509
return createDissolvingFlux(() -> commandBuilder.sunion(keys));
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/*
2+
* Copyright 2011-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.lettuce.core;
17+
18+
import io.lettuce.core.internal.LettuceAssert;
19+
import io.lettuce.core.protocol.CommandArgs;
20+
21+
/**
22+
* Argument list builder for the Redis <a href="https://redis.io/commands/lcs">LCS</a> command. Static import the methods from
23+
* {@link LcsArgs.Builder} and call the methods: {@code keys(…)} .
24+
* <p>
25+
* {@link LcsArgs} is a mutable object and instances should be used only once to avoid shared mutable state.
26+
*
27+
* @author Seonghwan Lee
28+
* @since 6.6
29+
*/
30+
public class LcsArgs implements CompositeArgument {
31+
32+
private boolean justLen;
33+
34+
private int minMatchLen;
35+
36+
private boolean withMatchLen;
37+
38+
private boolean withIdx;
39+
40+
private String[] keys;
41+
42+
/**
43+
* Builder entry points for {@link LcsArgs}.
44+
*/
45+
public static class Builder {
46+
47+
/**
48+
* Utility constructor.
49+
*/
50+
private Builder() {
51+
}
52+
53+
/**
54+
* Creates new {@link LcsArgs} by keys.
55+
*
56+
* @return new {@link LcsArgs} with {@literal By KEYS} set.
57+
*/
58+
public static LcsArgs keys(String... keys) {
59+
return new LcsArgs().by(keys);
60+
}
61+
62+
}
63+
64+
/**
65+
* restrict the list of matches to the ones of a given minimal length.
66+
*
67+
* @return {@code this} {@link LcsArgs}.
68+
*/
69+
public LcsArgs minMatchLen(int minMatchLen) {
70+
this.minMatchLen = minMatchLen;
71+
return this;
72+
}
73+
74+
/**
75+
* Request just the length of the match for results.
76+
*
77+
* @return {@code this} {@link LcsArgs}.
78+
*/
79+
public LcsArgs justLen() {
80+
justLen = true;
81+
return this;
82+
}
83+
84+
/**
85+
* Request match len for results.
86+
*
87+
* @return {@code this} {@link LcsArgs}.
88+
*/
89+
public LcsArgs withMatchLen() {
90+
withMatchLen = true;
91+
return this;
92+
}
93+
94+
/**
95+
* Request match position in each strings for results.
96+
*
97+
* @return {@code this} {@link LcsArgs}.
98+
*/
99+
public LcsArgs withIdx() {
100+
withIdx = true;
101+
return this;
102+
}
103+
104+
public LcsArgs by(String... keys) {
105+
LettuceAssert.notEmpty(keys, "Keys must not be empty");
106+
107+
this.keys = keys;
108+
return this;
109+
}
110+
111+
public boolean isWithIdx() {
112+
return withIdx;
113+
}
114+
115+
@Override
116+
public <K, V> void build(CommandArgs<K, V> args) {
117+
for (String key : keys) {
118+
args.add(key);
119+
}
120+
if (justLen) {
121+
args.add("LEN");
122+
}
123+
if (withIdx) {
124+
args.add("IDX");
125+
}
126+
127+
if (minMatchLen > 0) {
128+
args.add("MINMATCHLEN");
129+
args.add(minMatchLen);
130+
}
131+
132+
if (withMatchLen) {
133+
args.add("WITHMATCHLEN");
134+
}
135+
}
136+
137+
}

src/main/java/io/lettuce/core/RedisCommandBuilder.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2912,6 +2912,14 @@ Command<K, V, StringMatchResult> stralgoLcs(StrAlgoArgs strAlgoArgs) {
29122912
return createCommand(STRALGO, new StringMatchResultOutput<>(codec), args);
29132913
}
29142914

2915+
Command<K, V, StringMatchResult> lcs(LcsArgs lcsArgs) {
2916+
LettuceAssert.notNull(lcsArgs, "lcsArgs" + MUST_NOT_BE_NULL);
2917+
2918+
CommandArgs<K, V> args = new CommandArgs<>(codec);
2919+
lcsArgs.build(args);
2920+
return createCommand(LCS, new StringMatchResultOutput<>(codec), args);
2921+
}
2922+
29152923
Command<K, V, Set<V>> sunion(K... keys) {
29162924
notEmpty(keys);
29172925

src/main/java/io/lettuce/core/api/async/RedisStringAsyncCommands.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import io.lettuce.core.KeyValue;
2828
import io.lettuce.core.RedisFuture;
2929
import io.lettuce.core.SetArgs;
30+
import io.lettuce.core.LcsArgs;
3031
import io.lettuce.core.StrAlgoArgs;
3132
import io.lettuce.core.StringMatchResult;
3233
import io.lettuce.core.output.KeyValueStreamingChannel;
@@ -424,8 +425,26 @@ public interface RedisStringAsyncCommands<K, V> {
424425
* @return StringMatchResult.
425426
* @since 6.0
426427
*/
428+
@Deprecated
427429
RedisFuture<StringMatchResult> stralgoLcs(StrAlgoArgs strAlgoArgs);
428430

431+
/**
432+
* The LCS command implements the longest common subsequence algorithm.
433+
*
434+
* <ul>
435+
* <li>Without modifiers the string representing the longest common substring is returned.</li>
436+
* <li>When {@link LcsArgs#justLen() LEN} is given the command returns the length of the longest common substring.</li>
437+
* <li>When {@link LcsArgs#withIdx() IDX} is given the command returns an array with the LCS length and all the ranges in
438+
* both the strings, start and end offset for each string, where there are matches. When {@link LcsArgs#withMatchLen()
439+
* WITHMATCHLEN} is given each array representing a match will also have the length of the match.</li>
440+
* </ul>
441+
*
442+
* @param lcsArgs command arguments.
443+
* @return StringMatchResult.
444+
* @since 6.6
445+
*/
446+
RedisFuture<StringMatchResult> lcs(LcsArgs lcsArgs);
447+
429448
/**
430449
* Get the length of the value stored in a key.
431450
*

src/main/java/io/lettuce/core/api/reactive/RedisStringReactiveCommands.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import io.lettuce.core.KeyValue;
2929
import io.lettuce.core.SetArgs;
3030
import io.lettuce.core.StrAlgoArgs;
31+
import io.lettuce.core.LcsArgs;
3132
import io.lettuce.core.StringMatchResult;
3233
import io.lettuce.core.Value;
3334
import io.lettuce.core.output.KeyValueStreamingChannel;
@@ -428,8 +429,26 @@ public interface RedisStringReactiveCommands<K, V> {
428429
* @return StringMatchResult.
429430
* @since 6.0
430431
*/
432+
@Deprecated
431433
Mono<StringMatchResult> stralgoLcs(StrAlgoArgs strAlgoArgs);
432434

435+
/**
436+
* The LCS command implements the longest common subsequence algorithm.
437+
*
438+
* <ul>
439+
* <li>Without modifiers the string representing the longest common substring is returned.</li>
440+
* <li>When {@link LcsArgs#justLen() LEN} is given the command returns the length of the longest common substring.</li>
441+
* <li>When {@link LcsArgs#withIdx() IDX} is given the command returns an array with the LCS length and all the ranges in
442+
* both the strings, start and end offset for each string, where there are matches. When {@link LcsArgs#withMatchLen()
443+
* WITHMATCHLEN} is given each array representing a match will also have the length of the match.</li>
444+
* </ul>
445+
*
446+
* @param lcsArgs command arguments.
447+
* @return StringMatchResult.
448+
* @since 6.6
449+
*/
450+
Mono<StringMatchResult> lcs(LcsArgs lcsArgs);
451+
433452
/**
434453
* Get the length of the value stored in a key.
435454
*

src/main/java/io/lettuce/core/api/sync/RedisStringCommands.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import io.lettuce.core.KeyValue;
2828
import io.lettuce.core.SetArgs;
2929
import io.lettuce.core.StrAlgoArgs;
30+
import io.lettuce.core.LcsArgs;
3031
import io.lettuce.core.StringMatchResult;
3132
import io.lettuce.core.output.KeyValueStreamingChannel;
3233

@@ -423,8 +424,26 @@ public interface RedisStringCommands<K, V> {
423424
* @return StringMatchResult.
424425
* @since 6.0
425426
*/
427+
@Deprecated
426428
StringMatchResult stralgoLcs(StrAlgoArgs strAlgoArgs);
427429

430+
/**
431+
* The LCS command implements the longest common subsequence algorithm.
432+
*
433+
* <ul>
434+
* <li>Without modifiers the string representing the longest common substring is returned.</li>
435+
* <li>When {@link LcsArgs#justLen() LEN} is given the command returns the length of the longest common substring.</li>
436+
* <li>When {@link LcsArgs#withIdx() IDX} is given the command returns an array with the LCS length and all the ranges in
437+
* both the strings, start and end offset for each string, where there are matches. When {@link LcsArgs#withMatchLen()
438+
* WITHMATCHLEN} is given each array representing a match will also have the length of the match.</li>
439+
* </ul>
440+
*
441+
* @param lcsArgs command arguments.
442+
* @return StringMatchResult.
443+
* @since 6.6
444+
*/
445+
StringMatchResult lcs(LcsArgs lcsArgs);
446+
428447
/**
429448
* Get the length of the value stored in a key.
430449
*

src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionStringAsyncCommands.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import io.lettuce.core.SetArgs;
2929
import io.lettuce.core.StrAlgoArgs;
3030
import io.lettuce.core.StringMatchResult;
31+
import io.lettuce.core.LcsArgs;
3132
import io.lettuce.core.output.KeyValueStreamingChannel;
3233

3334
/**
@@ -425,6 +426,23 @@ public interface NodeSelectionStringAsyncCommands<K, V> {
425426
*/
426427
AsyncExecutions<StringMatchResult> stralgoLcs(StrAlgoArgs strAlgoArgs);
427428

429+
/**
430+
* The LCS command implements the longest common subsequence algorithm.
431+
*
432+
* <ul>
433+
* <li>Without modifiers the string representing the longest common substring is returned.</li>
434+
* <li>When {@link LcsArgs#justLen() LEN} is given the command returns the length of the longest common substring.</li>
435+
* <li>When {@link LcsArgs#withIdx() IDX} is given the command returns an array with the LCS length and all the ranges in
436+
* both the strings, start and end offset for each string, where there are matches. When {@link LcsArgs#withMatchLen()
437+
* WITHMATCHLEN} is given each array representing a match will also have the length of the match.</li>
438+
* </ul>
439+
*
440+
* @param lcsArgs command arguments.
441+
* @return StringMatchResult.
442+
* @since 6.6
443+
*/
444+
AsyncExecutions<StringMatchResult> lcs(LcsArgs lcsArgs);
445+
428446
/**
429447
* Get the length of the value stored in a key.
430448
*

src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionStringCommands.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import io.lettuce.core.SetArgs;
2929
import io.lettuce.core.StrAlgoArgs;
3030
import io.lettuce.core.StringMatchResult;
31+
import io.lettuce.core.LcsArgs;
3132
import io.lettuce.core.output.KeyValueStreamingChannel;
3233

3334
/**
@@ -425,6 +426,23 @@ public interface NodeSelectionStringCommands<K, V> {
425426
*/
426427
Executions<StringMatchResult> stralgoLcs(StrAlgoArgs strAlgoArgs);
427428

429+
/**
430+
* The LCS command implements the longest common subsequence algorithm.
431+
*
432+
* <ul>
433+
* <li>Without modifiers the string representing the longest common substring is returned.</li>
434+
* <li>When {@link LcsArgs#justLen() LEN} is given the command returns the length of the longest common substring.</li>
435+
* <li>When {@link LcsArgs#withIdx() IDX} is given the command returns an array with the LCS length and all the ranges in
436+
* both the strings, start and end offset for each string, where there are matches. When {@link LcsArgs#withMatchLen()
437+
* WITHMATCHLEN} is given each array representing a match will also have the length of the match.</li>
438+
* </ul>
439+
*
440+
* @param lcsArgs command arguments.
441+
* @return StringMatchResult.
442+
* @since 6.6
443+
*/
444+
Executions<StringMatchResult> lcs(LcsArgs lcsArgs);
445+
428446
/**
429447
* Get the length of the value stored in a key.
430448
*

src/main/java/io/lettuce/core/protocol/CommandType.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public enum CommandType implements ProtocolKeyword {
5050

5151
// String
5252

53-
APPEND, GET, GETDEL, GETEX, GETRANGE, GETSET, MGET, MSET, MSETNX, SET, SETEX, PSETEX, SETNX, SETRANGE, STRLEN, STRALGO,
53+
APPEND, GET, GETDEL, GETEX, GETRANGE, GETSET, MGET, MSET, MSETNX, SET, SETEX, PSETEX, SETNX, SETRANGE, STRLEN, STRALGO, LCS,
5454

5555
// Numeric
5656

0 commit comments

Comments
 (0)