From d8bdb544de3e0ae701814aa18fbba48953060937 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Mon, 10 Nov 2025 13:15:38 +0100 Subject: [PATCH 1/2] Prepare issue branch. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0e3024e099..34b2ad6400 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-redis - 4.0.0-SNAPSHOT + 4.0.0-GH-3256-SNAPSHOT Spring Data Redis Spring Data module for Redis From c61b24bf37b7084bf214a192125d0dfb214d9678 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Mon, 10 Nov 2025 13:16:18 +0100 Subject: [PATCH 2/2] Add incrementScore to RedisZSet. --- .../support/collections/DefaultRedisZSet.java | 8 +++++++ .../redis/support/collections/RedisZSet.java | 14 ++++++++++++ .../AbstractRedisZSetTestIntegration.java | 22 +++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/src/main/java/org/springframework/data/redis/support/collections/DefaultRedisZSet.java b/src/main/java/org/springframework/data/redis/support/collections/DefaultRedisZSet.java index 63a0e46895..83682b5fa2 100644 --- a/src/main/java/org/springframework/data/redis/support/collections/DefaultRedisZSet.java +++ b/src/main/java/org/springframework/data/redis/support/collections/DefaultRedisZSet.java @@ -30,6 +30,7 @@ import org.springframework.data.redis.core.RedisOperations; import org.springframework.data.redis.core.ScanOptions; import org.springframework.data.redis.core.ZSetOperations.TypedTuple; +import org.springframework.util.Assert; /** * Default implementation for {@link RedisZSet}. Note that the collection support works only with normal, @@ -322,6 +323,13 @@ public boolean addIfAbsent(E e, double score) { return result; } + @Override + public Double incrementScore(E value, Number delta) { + + Assert.notNull(delta, "Delta must not be null"); + return boundZSetOps.incrementScore(value, delta.doubleValue()); + } + @Override public void clear() { boundZSetOps.removeRange(0, -1); diff --git a/src/main/java/org/springframework/data/redis/support/collections/RedisZSet.java b/src/main/java/org/springframework/data/redis/support/collections/RedisZSet.java index 02d5fe98e2..e32b247c35 100644 --- a/src/main/java/org/springframework/data/redis/support/collections/RedisZSet.java +++ b/src/main/java/org/springframework/data/redis/support/collections/RedisZSet.java @@ -28,6 +28,7 @@ import org.springframework.data.redis.connection.zset.Tuple; import org.springframework.data.redis.core.BoundZSetOperations; import org.springframework.data.redis.core.RedisOperations; +import org.springframework.data.redis.core.ZSetOperations; import org.springframework.data.redis.core.ZSetOperations.TypedTuple; /** @@ -564,6 +565,19 @@ default boolean addIfAbsent(E e) { */ Double score(Object o); + /** + * Increment the score of element with {@code value} in sorted set by {@code delta}. + * + * @param value the value. + * @param delta the delta to add. Can be negative. Must not be {@literal null}. + * @return the new score after increment, or {@literal null} when used in pipeline / transaction. + * @throws IllegalArgumentException if delta is {@literal null}. + * @see ZSetOperations#incrementScore(Object, Object, double) + * @see Redis Documentation: ZINCRBY + * @since 4.1 + */ + Double incrementScore(E value, Number delta); + /** * Returns the rank (position) of the given element in the set, in ascending order. Returns null if the element is not * contained by the set. diff --git a/src/test/java/org/springframework/data/redis/support/collections/AbstractRedisZSetTestIntegration.java b/src/test/java/org/springframework/data/redis/support/collections/AbstractRedisZSetTestIntegration.java index 541989ebd9..a2744b293e 100644 --- a/src/test/java/org/springframework/data/redis/support/collections/AbstractRedisZSetTestIntegration.java +++ b/src/test/java/org/springframework/data/redis/support/collections/AbstractRedisZSetTestIntegration.java @@ -297,6 +297,28 @@ void testScore() { assertThat(zSet.score(t3)).isEqualTo(Double.valueOf(5)); } + @Test // GH-3256 + void testIncrementScore() { + + T value1 = getT(); + T value2 = getT(); + + // Add element with initial score + zSet.add(value1, 2.5); + + // Increment score + assertThat(zSet.incrementScore(value1, 3.2)).isEqualTo(Double.valueOf(5.7)); + assertThat(zSet.score(value1)).isEqualTo(Double.valueOf(5.7)); + + // Test with negative delta (decrement) + assertThat(zSet.incrementScore(value1, -1.5)).isEqualTo(Double.valueOf(4.2)); + assertThat(zSet.score(value1)).isEqualTo(Double.valueOf(4.2)); + + // Test incrementing non-existent element (should create it with delta as score) + assertThat(zSet.incrementScore(value2, 10.0)).isEqualTo(Double.valueOf(10.0)); + assertThat(zSet.score(value2)).isEqualTo(Double.valueOf(10.0)); + } + @Test void testDefaultScore() { assertThat(zSet.getDefaultScore()).isCloseTo(1, Offset.offset(0d));