Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit b09f752

Browse files
Kiminnionobc
authored andcommitted
Add support for Redis SINTERCARD command.
This commit adds support for Redis 7.0+ SINTERCARD command in Spring Data Redis. The `sInterCard` API has been added to SetCommands and ClusterSetCommands for both Jedis and Lettuce. The high-level `intersectSize` API has been added to SetOperations implementations as well. Original Pull Request: #3210 Resolves: #2906 Signed-off-by: Kiminni <imk0980@gmail.com>
1 parent b8e52f8 commit b09f752

19 files changed

+417
-0
lines changed

‎src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
* @author Dennis Neufeld
8383
* @author Shyngys Sapraliyev
8484
* @author Jeonggyu Choi
85+
* @author Mingi Lee
8586
*/
8687
@NullUnmarked
8788
@SuppressWarnings({ "ConstantConditions", "deprecation" })
@@ -832,6 +833,11 @@ public Long sInterStore(byte[] destKey, byte[]... keys) {
832833
return convertAndReturn(delegate.sInterStore(destKey, keys), Converters.identityConverter());
833834
}
834835

836+
@Override
837+
public Long sInterCard(byte[]... keys) {
838+
return convertAndReturn(delegate.sInterCard(keys), Converters.identityConverter());
839+
}
840+
835841
@Override
836842
public Boolean sIsMember(byte[] key, byte[] value) {
837843
return convertAndReturn(delegate.sIsMember(key, value), Converters.identityConverter());
@@ -1824,6 +1830,11 @@ public Long sInterStore(String destKey, String... keys) {
18241830
return sInterStore(serialize(destKey), serializeMulti(keys));
18251831
}
18261832

1833+
@Override
1834+
public Long sInterCard(String... keys) {
1835+
return sInterCard(serializeMulti(keys));
1836+
}
1837+
18271838
@Override
18281839
public Boolean sIsMember(String key, String value) {
18291840
return sIsMember(serialize(key), serialize(value));

‎src/main/java/org/springframework/data/redis/connection/DefaultedRedisConnection.java‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
* @author Dennis Neufeld
6868
* @author Shyngys Sapraliyev
6969
* @author Tihomir Mateev
70+
* @author Mingi Lee
7071
* @since 2.0
7172
*/
7273
@Deprecated
@@ -890,6 +891,13 @@ default Long sInterStore(byte[] destKey, byte[]... keys) {
890891
return setCommands().sInterStore(destKey, keys);
891892
}
892893

894+
/** @deprecated in favor of {@link RedisConnection#setCommands()}}. */
895+
@Override
896+
@Deprecated
897+
default Long sInterCard(byte[]... keys) {
898+
return setCommands().sInterCard(keys);
899+
}
900+
893901
/** @deprecated in favor of {@link RedisConnection#setCommands()}}. */
894902
@Override
895903
@Deprecated

‎src/main/java/org/springframework/data/redis/connection/ReactiveSetCommands.java‎

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
*
4444
* @author Christoph Strobl
4545
* @author Mark Paluch
46+
* @author Mingi Lee
4647
* @since 2.0
4748
*/
4849
public interface ReactiveSetCommands {
@@ -775,6 +776,73 @@ default Mono<Long> sInterStore(ByteBuffer destinationKey, Collection<ByteBuffer>
775776
*/
776777
Flux<NumericResponse<SInterStoreCommand, Long>> sInterStore(Publisher<SInterStoreCommand> commands);
777778

779+
/**
780+
* {@code SINTERCARD} command parameters.
781+
*
782+
* @author Mingi Lee
783+
* @since 4.0
784+
* @see <a href="https://redis.io/commands/sintercard">Redis Documentation: SINTERCARD</a>
785+
*/
786+
class SInterCardCommand implements Command {
787+
788+
private final List<ByteBuffer> keys;
789+
790+
private SInterCardCommand(List<ByteBuffer> keys) {
791+
this.keys = keys;
792+
}
793+
794+
/**
795+
* Creates a new {@link SInterCardCommand} given a {@link Collection} of keys.
796+
*
797+
* @param keys must not be {@literal null}.
798+
* @return a new {@link SInterCardCommand} for a {@link Collection} of keys.
799+
*/
800+
public static SInterCardCommand keys(Collection<ByteBuffer> keys) {
801+
802+
Assert.notNull(keys, "Keys must not be null");
803+
804+
return new SInterCardCommand(new ArrayList<>(keys));
805+
}
806+
807+
@Override
808+
public @Nullable ByteBuffer getKey() {
809+
return null;
810+
}
811+
812+
/**
813+
* @return never {@literal null}.
814+
*/
815+
public List<ByteBuffer> getKeys() {
816+
return keys;
817+
}
818+
}
819+
820+
/**
821+
* Returns the cardinality of the set which would result from the intersection of all given sets at {@literal keys}.
822+
*
823+
* @param keys must not be {@literal null}.
824+
* @return
825+
* @see <a href="https://redis.io/commands/sintercard">Redis Documentation: SINTERCARD</a>
826+
* @since 4.0
827+
*/
828+
default Mono<Long> sInterCard(Collection<ByteBuffer> keys) {
829+
830+
Assert.notNull(keys, "Keys must not be null");
831+
832+
return sInterCard(Mono.just(SInterCardCommand.keys(keys))).next().map(NumericResponse::getOutput);
833+
}
834+
835+
/**
836+
* Returns the cardinality of the set which would result from the intersection of all given sets at
837+
* {@link SInterCardCommand#getKeys()}.
838+
*
839+
* @param commands must not be {@literal null}.
840+
* @return
841+
* @see <a href="https://redis.io/commands/sintercard">Redis Documentation: SINTERCARD</a>
842+
* @since 4.0
843+
*/
844+
Flux<NumericResponse<SInterCardCommand, Long>> sInterCard(Publisher<SInterCardCommand> commands);
845+
778846
/**
779847
* {@code SUNION} command parameters.
780848
*

‎src/main/java/org/springframework/data/redis/connection/RedisSetCommands.java‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
* @author Costin Leau
3030
* @author Christoph Strobl
3131
* @author Mark Paluch
32+
* @author Mingi Lee
3233
* @see RedisCommands
3334
*/
3435
@NullUnmarked
@@ -153,6 +154,16 @@ public interface RedisSetCommands {
153154
*/
154155
Long sInterStore(byte @NonNull [] destKey, byte @NonNull [] @NonNull... keys);
155156

157+
/**
158+
* Returns the cardinality of the set which would result from the intersection of all the given sets.
159+
*
160+
* @param keys must not be {@literal null}.
161+
* @return {@literal null} when used in pipeline / transaction.
162+
* @see <a href="https://redis.io/commands/sintercard">Redis Documentation: SINTERCARD</a>
163+
* @since 4.0
164+
*/
165+
Long sInterCard(byte @NonNull [] @NonNull... keys);
166+
156167
/**
157168
* Union all sets at given {@code keys}.
158169
*

‎src/main/java/org/springframework/data/redis/connection/StringRedisConnection.java‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
* @author ihaohong
7575
* @author Shyngys Sapraliyev
7676
* @author Jeonggyu Choi
77+
* @author Mingi Lee
7778
* @see RedisCallback
7879
* @see RedisSerializer
7980
* @see StringRedisTemplate
@@ -1169,6 +1170,17 @@ String bLMove(@NonNull String sourceKey, @NonNull String destinationKey, @NonNul
11691170
*/
11701171
Long sInterStore(@NonNull String destKey, @NonNull String @NonNull... keys);
11711172

1173+
/**
1174+
* Returns the cardinality of the set which would result from the intersection of all the given sets.
1175+
*
1176+
* @param keys must not be {@literal null}.
1177+
* @return
1178+
* @see <a href="https://redis.io/commands/sintercard">Redis Documentation: SINTERCARD</a>
1179+
* @see RedisSetCommands#sInterCard(byte[]...)
1180+
* @since 4.0
1181+
*/
1182+
Long sInterCard(@NonNull String @NonNull... keys);
1183+
11721184
/**
11731185
* Union all sets at given {@code keys}.
11741186
*

‎src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterSetCommands.java‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
/**
4141
* @author Christoph Strobl
4242
* @author Mark Paluch
43+
* @author Mingi Lee
4344
* @since 2.0
4445
*/
4546
class JedisClusterSetCommands implements RedisSetCommands {
@@ -230,6 +231,25 @@ public Long sInterStore(byte[] destKey, byte[]... keys) {
230231
return sAdd(destKey, result.toArray(new byte[result.size()][]));
231232
}
232233

234+
@Override
235+
public Long sInterCard(byte[]... keys) {
236+
237+
Assert.notNull(keys, "Keys must not be null");
238+
Assert.noNullElements(keys, "Keys must not contain null elements");
239+
240+
if (ClusterSlotHashUtil.isSameSlotForAllKeys(keys)) {
241+
try {
242+
return connection.getCluster().sintercard(keys);
243+
} catch (Exception ex) {
244+
throw convertJedisAccessException(ex);
245+
}
246+
}
247+
248+
// For multi-slot clusters, calculate intersection cardinality by performing intersection
249+
Set<byte[]> result = sInter(keys);
250+
return (long) result.size();
251+
}
252+
233253
@Override
234254
public Set<byte[]> sUnion(byte[]... keys) {
235255

‎src/main/java/org/springframework/data/redis/connection/jedis/JedisSetCommands.java‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
/**
3939
* @author Christoph Strobl
4040
* @author Mark Paluch
41+
* @author Mingi Lee
4142
* @since 2.0
4243
*/
4344
@NullUnmarked
@@ -105,6 +106,15 @@ public Long sInterStore(byte @NonNull [] destKey, byte @NonNull [] @NonNull... k
105106
return connection.invoke().just(Jedis::sinterstore, PipelineBinaryCommands::sinterstore, destKey, keys);
106107
}
107108

109+
@Override
110+
public Long sInterCard(byte @NonNull [] @NonNull... keys) {
111+
112+
Assert.notNull(keys, "Keys must not be null");
113+
Assert.noNullElements(keys, "Keys must not contain null elements");
114+
115+
return connection.invoke().just(Jedis::sintercard, PipelineBinaryCommands::sintercard, keys);
116+
}
117+
108118
@Override
109119
public Boolean sIsMember(byte @NonNull [] key, byte @NonNull [] value) {
110120

‎src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterSetCommands.java‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
/**
3232
* @author Christoph Strobl
3333
* @author Mark Paluch
34+
* @author Mingi Lee
3435
* @since 2.0
3536
*/
3637
class LettuceClusterSetCommands extends LettuceSetCommands {
@@ -118,6 +119,21 @@ public Long sInterStore(byte[] destKey, byte[]... keys) {
118119
return sAdd(destKey, result.toArray(new byte[result.size()][]));
119120
}
120121

122+
@Override
123+
public Long sInterCard(byte[]... keys) {
124+
125+
Assert.notNull(keys, "Keys must not be null");
126+
Assert.noNullElements(keys, "Keys must not contain null elements");
127+
128+
if (ClusterSlotHashUtil.isSameSlotForAllKeys(keys)) {
129+
return super.sInterCard(keys);
130+
}
131+
132+
// For multi-slot clusters, calculate intersection cardinality by performing intersection
133+
Set<byte[]> result = sInter(keys);
134+
return (long) result.size();
135+
}
136+
121137
@Override
122138
public Set<byte[]> sUnion(byte[]... keys) {
123139

‎src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveSetCommands.java‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
/**
3737
* @author Christoph Strobl
3838
* @author Mark Paluch
39+
* @author Mingi Lee
3940
* @since 2.0
4041
*/
4142
class LettuceReactiveSetCommands implements ReactiveSetCommands {
@@ -175,6 +176,18 @@ public Flux<NumericResponse<SInterStoreCommand, Long>> sInterStore(Publisher<SIn
175176
}));
176177
}
177178

179+
@Override
180+
public Flux<NumericResponse<SInterCardCommand, Long>> sInterCard(Publisher<SInterCardCommand> commands) {
181+
182+
return connection.execute(cmd -> Flux.from(commands).concatMap(command -> {
183+
184+
Assert.notNull(command.getKeys(), "Keys must not be null");
185+
186+
return cmd.sintercard(command.getKeys().toArray(new ByteBuffer[0]))
187+
.map(value -> new NumericResponse<>(command, value));
188+
}));
189+
}
190+
178191
@Override
179192
public Flux<CommandResponse<SUnionCommand, Flux<ByteBuffer>>> sUnion(Publisher<SUnionCommand> commands) {
180193

‎src/main/java/org/springframework/data/redis/connection/lettuce/LettuceSetCommands.java‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
/**
4040
* @author Christoph Strobl
4141
* @author Mark Paluch
42+
* @author Mingi Lee
4243
* @since 2.0
4344
*/
4445
@NullUnmarked
@@ -106,6 +107,15 @@ public Long sInterStore(byte @NonNull [] destKey, byte @NonNull [] @NonNull... k
106107
return connection.invoke().just(RedisSetAsyncCommands::sinterstore, destKey, keys);
107108
}
108109

110+
@Override
111+
public Long sInterCard(byte @NonNull [] @NonNull... keys) {
112+
113+
Assert.notNull(keys, "Keys must not be null");
114+
Assert.noNullElements(keys, "Keys must not contain null elements");
115+
116+
return connection.invoke().just(RedisSetAsyncCommands::sintercard, keys);
117+
}
118+
109119
@Override
110120
public Boolean sIsMember(byte @NonNull [] key, byte @NonNull [] value) {
111121

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /