Skip to content

Commit

Permalink
Add multiple reactive keys exist checker
Browse files Browse the repository at this point in the history
  • Loading branch information
AnneMayor authored and pranne1224 committed Mar 8, 2025
1 parent 06f3591 commit 79ee7fd
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,14 @@ default Mono<Boolean> exists(ByteBuffer key) {

return exists(Mono.just(new KeyCommand(key))).next().map(BooleanResponse::getOutput);
}
/**
* Determine the number of given {@literal keys} that exist.
*
* @param keys must not be {@literal null} or {@literal empty}.
* @return {@link Mono} emitting {@literal the number of existing keys}.
* @see <a href="https://redis.io/docs/commands/exists/">Redis Documentation: EXISTS</a>
*/
Mono<Long> exists(List<ByteBuffer> keys);

/**
* Determine if given {@literal key} exists.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,4 +319,12 @@ public Mono<Duration> idletime(ByteBuffer key) {
public Mono<Long> refcount(ByteBuffer key) {
return connection.execute(cmd -> cmd.objectRefcount(key)).next();
}

@Override
public Mono<Long> exists(List<ByteBuffer> keys) {
Assert.notNull(keys, "Key list must not be null");
Assert.notEmpty(keys, "Key list must not be empty");

return connection.execute(cmd -> cmd.exists(keys.toArray(ByteBuffer[]::new))).next();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.time.Duration;
import java.time.Instant;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

Expand Down Expand Up @@ -402,6 +403,15 @@ default Flux<K> scan() {
*/
Mono<Duration> getExpire(K key);

/**
* Get the number of given {@code keys} that exists.
*
* @param keys must not be {@literal null} or {@literal empty}.
* @return the number of existing keys in redis. 0 if there are no existing keys.
* @see <a href="https://redis.io/docs/commands/exists/">Redis Documentation: EXISTS</a>
*/
Mono<Long> countExistingKeys(Collection<K> keys);

// -------------------------------------------------------------------------
// Methods dealing with Redis Lua scripts
// -------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.time.Duration;
import java.time.Instant;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -489,6 +490,14 @@ public Mono<Boolean> move(K key, int dbIndex) {
return doCreateMono(connection -> connection.keyCommands().move(rawKey(key), dbIndex));
}

@Override
public Mono<Long> countExistingKeys(Collection<K> keys) {
Assert.notNull(keys, "Keys must not be null");

ByteBuffer[] rawKeys = rawKeys(keys);
return doCreateMono(connection -> connection.keyCommands().exists(Arrays.asList(rawKeys)));
}

// -------------------------------------------------------------------------
// Methods dealing with Redis Lua scripts
// -------------------------------------------------------------------------
Expand Down Expand Up @@ -672,6 +681,17 @@ private ByteBuffer rawKey(K key) {
return getSerializationContext().getKeySerializationPair().getWriter().write(key);
}

private ByteBuffer[] rawKeys(Collection<K> keys) {
final ByteBuffer[] rawKeys = new ByteBuffer[keys.size()];

int i = 0;
for (K key : keys) {
rawKeys[i++] = rawKey(key);
}

return rawKeys;
}

@Nullable
private K readKey(ByteBuffer buffer) {
return getSerializationContext().getKeySerializationPair().getReader().read(buffer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,22 @@ void existsShouldReturnFalseForNonExistingKeys() {
connection.keyCommands().exists(KEY_1_BBUFFER).as(StepVerifier::create).expectNext(false).verifyComplete();
}

@ParameterizedRedisTest
void existsKeyReturnsKeyCount() {
nativeCommands.set(KEY_1, "1000");
nativeCommands.set(KEY_2, "2000");
nativeCommands.set(KEY_3, "3000");

connection.keyCommands().exists(List.of(KEY_1_BBUFFER, KEY_2_BBUFFER, KEY_3_BBUFFER)).as(StepVerifier::create)
.expectNext(3L).verifyComplete();
}

@ParameterizedRedisTest
void existsKeyReturnsZeroWhenKeyDoesNotExist() {
connection.keyCommands().exists(List.of(KEY_1_BBUFFER, KEY_2_BBUFFER, KEY_3_BBUFFER)).as(StepVerifier::create)
.expectNext(0L).verifyComplete();
}

@ParameterizedRedisTest // DATAREDIS-525
void typeShouldReturnTypeCorrectly() {

Expand Down Expand Up @@ -164,7 +180,7 @@ void renameShouldAlterKeyNameCorrectly() {
connection.keyCommands().rename(KEY_1_BBUFFER, KEY_2_BBUFFER).as(StepVerifier::create).expectNext(true)
.verifyComplete();
assertThat(nativeCommands.exists(KEY_2)).isEqualTo(1L);
assertThat(nativeCommands.exists(KEY_1)).isEqualTo(0L);
assertThat(nativeCommands.exists(KEY_1)).isZero();
}

@ParameterizedRedisTest // DATAREDIS-525
Expand All @@ -183,7 +199,7 @@ void renameNXShouldAlterKeyNameCorrectly() {
.verifyComplete();

assertThat(nativeCommands.exists(KEY_2)).isEqualTo(1L);
assertThat(nativeCommands.exists(KEY_1)).isEqualTo(0L);
assertThat(nativeCommands.exists(KEY_1)).isZero();
}

@ParameterizedRedisTest // DATAREDIS-525
Expand Down Expand Up @@ -395,7 +411,7 @@ void shouldMoveToDatabase() {
.expectNext(true) //
.expectComplete() //
.verify();
assertThat(nativeCommands.exists(KEY_1)).isEqualTo(0L);
assertThat(nativeCommands.exists(KEY_1)).isZero();
}

@ParameterizedRedisTest // DATAREDIS-694
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@

import java.time.Duration;
import java.time.Instant;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.*;
import java.util.function.Function;

import org.junit.jupiter.api.BeforeEach;
Expand Down Expand Up @@ -544,4 +541,24 @@ void listenToPatternLaterShouldReceiveChannelMessagesCorrectly() {
.thenCancel() //
.verify(Duration.ofSeconds(3));
}

@ParameterizedRedisTest
void countExistingKeysIfValidKeyExists() {

K key = keyFactory.instance();
K key2 = keyFactory.instance();
K key3 = keyFactory.instance();

redisTemplate.opsForValue().set(key, valueFactory.instance()).as(StepVerifier::create).expectNext(true).verifyComplete();
redisTemplate.opsForValue().set(key2, valueFactory.instance()).as(StepVerifier::create).expectNext(true).verifyComplete();
redisTemplate.opsForValue().set(key3, valueFactory.instance()).as(StepVerifier::create).expectNext(true).verifyComplete();

redisTemplate.countExistingKeys(Arrays.asList(key, key2, key3)).as(StepVerifier::create).expectNext(3L).verifyComplete();
}

@ParameterizedRedisTest
void countExistingKeysIfNotValidKeyExists() {
K key = keyFactory.instance();
redisTemplate.countExistingKeys(List.of(key)).as(StepVerifier::create).expectNext(0L).verifyComplete();
}
}

0 comments on commit 79ee7fd

Please sign in to comment.