Polishing.
Add getFirst/getLast to Reactive and Bound Operations. Simplify getLast implementation. Reorder methods, tweak Javadoc, add since tags. Original pull request: #2966 See #2937
This commit is contained in:
@@ -212,6 +212,24 @@ public interface BoundListOperations<K, V> extends BoundKeyOperations<K> {
|
||||
@Nullable
|
||||
Long remove(long count, Object value);
|
||||
|
||||
/**
|
||||
* Returns the first element from the list at the bound {@code key}.
|
||||
*
|
||||
* @return {@literal null} when used in pipeline / transaction.
|
||||
* @since 3.4
|
||||
*/
|
||||
@Nullable
|
||||
V getFirst();
|
||||
|
||||
/**
|
||||
* Returns the last element from the list at the bound {@code key}.
|
||||
*
|
||||
* @return {@literal null} when used in pipeline / transaction.
|
||||
* @since 3.4
|
||||
*/
|
||||
@Nullable
|
||||
V getLast();
|
||||
|
||||
/**
|
||||
* Get element at {@code index} form list at the bound key.
|
||||
*
|
||||
|
||||
@@ -368,6 +368,30 @@ public interface ListOperations<K, V> {
|
||||
@Nullable
|
||||
Long remove(K key, long count, Object value);
|
||||
|
||||
/**
|
||||
* Returns the first element from the list at {@code key}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @return {@literal null} when used in pipeline / transaction.
|
||||
* @since 3.4
|
||||
*/
|
||||
@Nullable
|
||||
default V getFirst(K key) {
|
||||
return index(key, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last element from the list at {@code key}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @return {@literal null} when used in pipeline / transaction.
|
||||
* @since 3.4
|
||||
*/
|
||||
@Nullable
|
||||
default V getLast(K key) {
|
||||
return index(key, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get element at {@code index} form list at {@code key}.
|
||||
*
|
||||
@@ -526,7 +550,8 @@ public interface ListOperations<K, V> {
|
||||
V rightPopAndLeftPush(K sourceKey, K destinationKey);
|
||||
|
||||
/**
|
||||
* Remove the last element from list at {@code sourceKey}, append it to {@code destinationKey} and return its value.<br>
|
||||
* Remove the last element from list at {@code sourceKey}, append it to {@code destinationKey} and return its
|
||||
* value.<br>
|
||||
* <b>Blocks connection</b> until element available or {@code timeout} reached.
|
||||
*
|
||||
* @param sourceKey must not be {@literal null}.
|
||||
@@ -540,7 +565,8 @@ public interface ListOperations<K, V> {
|
||||
V rightPopAndLeftPush(K sourceKey, K destinationKey, long timeout, TimeUnit unit);
|
||||
|
||||
/**
|
||||
* Remove the last element from list at {@code sourceKey}, append it to {@code destinationKey} and return its value.<br>
|
||||
* Remove the last element from list at {@code sourceKey}, append it to {@code destinationKey} and return its
|
||||
* value.<br>
|
||||
* <b>Blocks connection</b> until element available or {@code timeout} reached.
|
||||
*
|
||||
* @param sourceKey must not be {@literal null}.
|
||||
@@ -560,35 +586,5 @@ public interface ListOperations<K, V> {
|
||||
return rightPopAndLeftPush(sourceKey, destinationKey, TimeoutUtils.toSeconds(timeout), TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first element from list at {@code key}.
|
||||
*
|
||||
* @implSpec
|
||||
* The implementation in this interface returns the result of calling {@code index(key, 0)}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @return {@literal null} when used in pipeline / transaction.
|
||||
*/
|
||||
@Nullable
|
||||
default V getFirst(K key) {
|
||||
return index(key, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last element from list at {@code key}.
|
||||
*
|
||||
* @implSpec
|
||||
* If the result of calling {@code size(key)} is not null, The implementation in this interface returns the
|
||||
* result of calling {@code index(key, size - 1)}. Otherwise, it returns null.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @return {@literal null} when used in pipeline / transaction.
|
||||
*/
|
||||
@Nullable
|
||||
default V getLast(K key) {
|
||||
Long size = size(key);
|
||||
return size != null ? index(key, size - 1) : null;
|
||||
}
|
||||
|
||||
RedisOperations<K, V> getOperations();
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.util.Collection;
|
||||
|
||||
import org.springframework.data.redis.core.ListOperations.MoveFrom;
|
||||
import org.springframework.data.redis.core.ListOperations.MoveTo;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -276,6 +277,30 @@ public interface ReactiveListOperations<K, V> {
|
||||
*/
|
||||
Mono<Long> remove(K key, long count, Object value);
|
||||
|
||||
/**
|
||||
* Returns the first element from the list at {@code key}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @return
|
||||
* @since 3.4
|
||||
*/
|
||||
@Nullable
|
||||
default Mono<V> getFirst(K key) {
|
||||
return index(key, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last element from the list at {@code key}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @return
|
||||
* @since 3.4
|
||||
*/
|
||||
@Nullable
|
||||
default Mono<V> getLast(K key) {
|
||||
return index(key, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get element at {@code index} form list at {@code key}.
|
||||
*
|
||||
|
||||
@@ -349,7 +349,7 @@ public class DefaultRedisList<E> extends AbstractRedisCollection<E> implements R
|
||||
@Override
|
||||
@Nullable
|
||||
public E peek() {
|
||||
return listOps.index(0);
|
||||
return listOps.getFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -426,7 +426,7 @@ public class DefaultRedisList<E> extends AbstractRedisCollection<E> implements R
|
||||
@Override
|
||||
@Nullable
|
||||
public E peekLast() {
|
||||
return listOps.index(-1);
|
||||
return listOps.getLast();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -56,8 +56,7 @@ public class DefaultListOperationsIntegrationIntegrationTests<K, V> {
|
||||
private final ListOperations<K, V> listOps;
|
||||
|
||||
public DefaultListOperationsIntegrationIntegrationTests(RedisTemplate<K, V> redisTemplate,
|
||||
ObjectFactory<K> keyFactory,
|
||||
ObjectFactory<V> valueFactory) {
|
||||
ObjectFactory<K> keyFactory, ObjectFactory<V> valueFactory) {
|
||||
|
||||
this.redisTemplate = redisTemplate;
|
||||
this.keyFactory = keyFactory;
|
||||
@@ -347,6 +346,34 @@ public class DefaultListOperationsIntegrationIntegrationTests<K, V> {
|
||||
assertThat(listOps.range(target, 0, -1)).containsExactly(v4, v1);
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest // GH-2937
|
||||
void getFirst() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V v1 = valueFactory.instance();
|
||||
V v2 = valueFactory.instance();
|
||||
V v3 = valueFactory.instance();
|
||||
|
||||
listOps.rightPush(key, v1);
|
||||
listOps.rightPush(key, v2);
|
||||
listOps.rightPush(key, v3);
|
||||
assertThat(listOps.getFirst(key)).isEqualTo(v1);
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest // GH-2937
|
||||
void getLast() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V v1 = valueFactory.instance();
|
||||
V v2 = valueFactory.instance();
|
||||
V v3 = valueFactory.instance();
|
||||
|
||||
listOps.rightPush(key, v1);
|
||||
listOps.rightPush(key, v2);
|
||||
listOps.rightPush(key, v3);
|
||||
assertThat(listOps.getLast(key)).isEqualTo(v3);
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest // DATAREDIS-1196
|
||||
@EnabledOnCommand("LPOS")
|
||||
void indexOf() {
|
||||
@@ -378,31 +405,4 @@ public class DefaultListOperationsIntegrationIntegrationTests<K, V> {
|
||||
assertThat(listOps.lastIndexOf(key, v1)).isEqualTo(2);
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest // GH-2937
|
||||
void getFirst() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V v1 = valueFactory.instance();
|
||||
V v2 = valueFactory.instance();
|
||||
V v3 = valueFactory.instance();
|
||||
|
||||
listOps.rightPush(key, v1);
|
||||
listOps.rightPush(key, v2);
|
||||
listOps.rightPush(key, v3);
|
||||
assertThat(listOps.getFirst(key)).isEqualTo(v1);
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest // GH-2937
|
||||
void getLast() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V v1 = valueFactory.instance();
|
||||
V v2 = valueFactory.instance();
|
||||
V v3 = valueFactory.instance();
|
||||
|
||||
listOps.rightPush(key, v1);
|
||||
listOps.rightPush(key, v2);
|
||||
listOps.rightPush(key, v3);
|
||||
assertThat(listOps.getLast(key)).isEqualTo(v3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,10 @@
|
||||
*/
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.assertj.core.api.Assumptions.assumeThat;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.assertj.core.api.Assumptions.*;
|
||||
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Collection;
|
||||
@@ -33,8 +35,6 @@ import org.springframework.data.redis.test.condition.EnabledOnCommand;
|
||||
import org.springframework.data.redis.test.extension.parametrized.MethodSource;
|
||||
import org.springframework.data.redis.test.extension.parametrized.ParameterizedRedisTest;
|
||||
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link DefaultReactiveListOperations}.
|
||||
*
|
||||
@@ -417,6 +417,32 @@ public class DefaultReactiveListOperationsIntegrationTests<K, V> {
|
||||
listOperations.index(key, 1).as(StepVerifier::create).expectNext(value2).verifyComplete();
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest // GH-2937
|
||||
void getFirst() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V v1 = valueFactory.instance();
|
||||
V v2 = valueFactory.instance();
|
||||
V v3 = valueFactory.instance();
|
||||
|
||||
listOperations.rightPushAll(key, v1, v2, v3).as(StepVerifier::create).expectNext(3L).verifyComplete();
|
||||
|
||||
listOperations.getFirst(key).as(StepVerifier::create).expectNext(v1).verifyComplete();
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest // GH-2937
|
||||
void getLast() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V v1 = valueFactory.instance();
|
||||
V v2 = valueFactory.instance();
|
||||
V v3 = valueFactory.instance();
|
||||
|
||||
listOperations.rightPushAll(key, v1, v2, v3).as(StepVerifier::create).expectNext(3L).verifyComplete();
|
||||
|
||||
listOperations.getLast(key).as(StepVerifier::create).expectNext(v3).verifyComplete();
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest // DATAREDIS-1196
|
||||
@EnabledOnCommand("LPOS")
|
||||
void indexOf() {
|
||||
@@ -469,16 +495,9 @@ public class DefaultReactiveListOperationsIntegrationTests<K, V> {
|
||||
V value2 = valueFactory.instance();
|
||||
V value3 = valueFactory.instance();
|
||||
|
||||
listOperations.leftPushAll(key, value1, value2, value3)
|
||||
.as(StepVerifier::create)
|
||||
.expectNext(3L)
|
||||
.verifyComplete();
|
||||
listOperations.leftPushAll(key, value1, value2, value3).as(StepVerifier::create).expectNext(3L).verifyComplete();
|
||||
|
||||
listOperations.leftPop(key, 2)
|
||||
.as(StepVerifier::create)
|
||||
.expectNext(value3)
|
||||
.expectNext(value2)
|
||||
.verifyComplete();
|
||||
listOperations.leftPop(key, 2).as(StepVerifier::create).expectNext(value3).expectNext(value2).verifyComplete();
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest // DATAREDIS-602
|
||||
@@ -505,16 +524,9 @@ public class DefaultReactiveListOperationsIntegrationTests<K, V> {
|
||||
V value2 = valueFactory.instance();
|
||||
V value3 = valueFactory.instance();
|
||||
|
||||
listOperations.rightPushAll(key, value3, value2, value1)
|
||||
.as(StepVerifier::create)
|
||||
.expectNext(3L)
|
||||
.verifyComplete();
|
||||
listOperations.rightPushAll(key, value3, value2, value1).as(StepVerifier::create).expectNext(3L).verifyComplete();
|
||||
|
||||
listOperations.rightPop(key, 2)
|
||||
.as(StepVerifier::create)
|
||||
.expectNext(value1)
|
||||
.expectNext(value2)
|
||||
.verifyComplete();
|
||||
listOperations.rightPop(key, 2).as(StepVerifier::create).expectNext(value1).expectNext(value2).verifyComplete();
|
||||
}
|
||||
|
||||
@ParameterizedRedisTest // DATAREDIS-602
|
||||
|
||||
Reference in New Issue
Block a user