Skip to content

Commit 9ef5042

Browse files
committed
Polishing.
Refine Expiration TTL retrieval to reduce duplications, introduce ExpirationAdapter for converters. Original Pull Request: #3226 See: #3211
1 parent 0c93388 commit 9ef5042

File tree

8 files changed

+224
-111
lines changed

8 files changed

+224
-111
lines changed

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

Lines changed: 27 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ public String convert(byte[] source) {
132132
private class SerializingConverter implements Converter<String, byte[]> {
133133

134134
@Override
135-
public byte @Nullable[] convert(String source) {
135+
public byte @Nullable [] convert(String source) {
136136
return serializer.serialize(source);
137137
}
138138
}
@@ -393,9 +393,8 @@ public byte[] get(byte[] key) {
393393
return convertAndReturn(delegate.get(key), Converters.identityConverter());
394394
}
395395

396-
397396
@Override
398-
public byte @Nullable[] getDel(byte[] key) {
397+
public byte @Nullable [] getDel(byte[] key) {
399398
return convertAndReturn(delegate.getDel(key), Converters.identityConverter());
400399
}
401400

@@ -404,9 +403,8 @@ public byte[] get(byte[] key) {
404403
return convertAndReturn(delegate.getDel(serialize(key)), bytesToString);
405404
}
406405

407-
408406
@Override
409-
public byte @Nullable[] getEx(byte[] key, Expiration expiration) {
407+
public byte @Nullable [] getEx(byte[] key, Expiration expiration) {
410408
return convertAndReturn(delegate.getEx(key, expiration), Converters.identityConverter());
411409
}
412410

@@ -1387,8 +1385,7 @@ private org.springframework.data.domain.Range.Bound<byte[]> rawBound(
13871385
@SuppressWarnings("unchecked")
13881386
private GeoReference<byte[]> serialize(GeoReference<String> data) {
13891387
return data instanceof GeoReference.GeoMemberReference
1390-
? GeoReference
1391-
.fromMember(serializer.serialize(((GeoMemberReference<String>) data).getMember()))
1388+
? GeoReference.fromMember(serializer.serialize(((GeoMemberReference<String>) data).getMember()))
13921389
: (GeoReference) data;
13931390
}
13941391

@@ -1538,9 +1535,8 @@ public Double hIncrBy(String key, String field, double delta) {
15381535
return hIncrBy(serialize(key), serialize(field), delta);
15391536
}
15401537

1541-
15421538
@Override
1543-
public byte @Nullable[] hRandField(byte[] key) {
1539+
public byte @Nullable [] hRandField(byte[] key) {
15441540
return convertAndReturn(delegate.hRandField(key), Converters.identityConverter());
15451541
}
15461542

@@ -1627,8 +1623,10 @@ public List<String> hGetEx(String key, Expiration expiration, String... fields)
16271623
}
16281624

16291625
@Override
1630-
public Boolean hSetEx(@NonNull String key, @NonNull Map<@NonNull String, String> hashes, HashFieldSetOption condition, Expiration expiration) {
1631-
return convertAndReturn(delegate.hSetEx(serialize(key), serialize(hashes), condition, expiration), Converters.identityConverter());
1626+
public Boolean hSetEx(@NonNull String key, @NonNull Map<@NonNull String, String> hashes, HashFieldSetOption condition,
1627+
Expiration expiration) {
1628+
return convertAndReturn(delegate.hSetEx(serialize(key), serialize(hashes), condition, expiration),
1629+
Converters.identityConverter());
16321630
}
16331631

16341632
@Override
@@ -2563,8 +2561,7 @@ public Long hStrLen(byte[] key, byte[] field) {
25632561
}
25642562

25652563
public @Nullable List<Long> applyHashFieldExpiration(byte[] key,
2566-
org.springframework.data.redis.core.types.Expiration expiration,
2567-
ExpirationOptions options, byte[]... fields) {
2564+
org.springframework.data.redis.core.types.Expiration expiration, ExpirationOptions options, byte[]... fields) {
25682565
return this.delegate.applyHashFieldExpiration(key, expiration, options, fields);
25692566
}
25702567

@@ -2609,25 +2606,24 @@ public List<Long> hTtl(byte[] key, TimeUnit timeUnit, byte[]... fields) {
26092606
return this.delegate.hTtl(key, timeUnit, fields);
26102607
}
26112608

2612-
@Override
2613-
public List<byte[]> hGetDel(@NonNull byte[] key, @NonNull byte[]... fields) {
2614-
return convertAndReturn(delegate.hGetDel(key, fields), Converters.identityConverter());
2615-
}
2609+
@Override
2610+
public List<byte[]> hGetDel(@NonNull byte[] key, @NonNull byte[]... fields) {
2611+
return convertAndReturn(delegate.hGetDel(key, fields), Converters.identityConverter());
2612+
}
26162613

2617-
@Override
2618-
public List<byte[]> hGetEx(@NonNull byte[] key, @Nullable Expiration expiration, @NonNull byte[]... fields) {
2614+
@Override
2615+
public List<byte[]> hGetEx(@NonNull byte[] key, @Nullable Expiration expiration, @NonNull byte[]... fields) {
26192616
return convertAndReturn(delegate.hGetEx(key, expiration, fields), Converters.identityConverter());
26202617
}
26212618

2622-
@Override
2623-
public Boolean hSetEx(@NonNull byte[] key, @NonNull Map<byte[], byte[]> hashes, @NonNullHashFieldSetOption condition,
2624-
@Nullable Expiration expiration) {
2619+
@Override
2620+
public Boolean hSetEx(@NonNull byte[] key, @NonNull Map<byte[], byte[]> hashes, @NonNull HashFieldSetOption condition,
2621+
@Nullable Expiration expiration) {
26252622
return convertAndReturn(delegate.hSetEx(key, hashes, condition, expiration), Converters.identityConverter());
26262623
}
26272624

26282625
public @Nullable List<Long> applyExpiration(String key,
2629-
org.springframework.data.redis.core.types.Expiration expiration,
2630-
ExpirationOptions options, String... fields) {
2626+
org.springframework.data.redis.core.types.Expiration expiration, ExpirationOptions options, String... fields) {
26312627
return this.applyHashFieldExpiration(serialize(key), expiration, options, serializeMulti(fields));
26322628
}
26332629

@@ -2816,16 +2812,14 @@ public Set<String> zRevRangeByLex(String key, org.springframework.data.domain.Ra
28162812
}
28172813

28182814
@Override
2819-
public Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey,
2820-
org.springframework.data.domain.Range<byte[]> range,
2821-
org.springframework.data.redis.connection.Limit limit) {
2822-
return convertAndReturn(delegate.zRangeStoreByLex(dstKey, srcKey, range, limit),
2823-
Converters.identityConverter());
2815+
public Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<byte[]> range,
2816+
org.springframework.data.redis.connection.Limit limit) {
2817+
return convertAndReturn(delegate.zRangeStoreByLex(dstKey, srcKey, range, limit), Converters.identityConverter());
28242818
}
28252819

28262820
@Override
2827-
public Long zRangeStoreByLex(String dstKey, String srcKey,
2828-
org.springframework.data.domain.Range<String> range, org.springframework.data.redis.connection.Limit limit) {
2821+
public Long zRangeStoreByLex(String dstKey, String srcKey, org.springframework.data.domain.Range<String> range,
2822+
org.springframework.data.redis.connection.Limit limit) {
28292823
return convertAndReturn(delegate.zRangeStoreByLex(serialize(dstKey), serialize(srcKey), serialize(range), limit),
28302824
Converters.identityConverter());
28312825
}
@@ -2846,9 +2840,8 @@ public Long zRangeStoreRevByLex(String dstKey, String srcKey, org.springframewor
28462840
@Override
28472841
public Long zRangeStoreByScore(byte[] dstKey, byte[] srcKey,
28482842
org.springframework.data.domain.Range<? extends Number> range,
2849-
org.springframework.data.redis.connection.Limit limit) {
2850-
return convertAndReturn(delegate.zRangeStoreByScore(dstKey, srcKey, range, limit),
2851-
Converters.identityConverter());
2843+
org.springframework.data.redis.connection.Limit limit) {
2844+
return convertAndReturn(delegate.zRangeStoreByScore(dstKey, srcKey, range, limit), Converters.identityConverter());
28522845
}
28532846

28542847
@Override

src/main/java/org/springframework/data/redis/connection/RedisHashCommands.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ public interface RedisHashCommands {
281281
}
282282

283283
if (ObjectUtils.nullSafeEquals(ExpirationOptions.none(), options)) {
284-
if (ObjectUtils.nullSafeEquals(TimeUnit.MILLISECONDS, expiration.getTimeUnit())) {
284+
if (expiration.isPrecise()) {
285285
if (expiration.isUnixTimestamp()) {
286286
return hpExpireAt(key, expiration.getExpirationTimeInMilliseconds(), fields);
287287
}
@@ -293,7 +293,7 @@ public interface RedisHashCommands {
293293
return hExpire(key, expiration.getExpirationTimeInSeconds(), fields);
294294
}
295295

296-
if (ObjectUtils.nullSafeEquals(TimeUnit.MILLISECONDS, expiration.getTimeUnit())) {
296+
if (expiration.isPrecise()) {
297297
if (expiration.isUnixTimestamp()) {
298298
return hpExpireAt(key, expiration.getExpirationTimeInMilliseconds(), options.getCondition(), fields);
299299
}

src/main/java/org/springframework/data/redis/connection/RedisKeyCommands.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ default Boolean applyExpiration(byte @NonNull [] key,
201201
}
202202

203203
if (ObjectUtils.nullSafeEquals(ExpirationOptions.none(), options)) {
204-
if (ObjectUtils.nullSafeEquals(TimeUnit.MILLISECONDS, expiration.getTimeUnit())) {
204+
if (expiration.isPrecise()) {
205205
if (expiration.isUnixTimestamp()) {
206206
return expireAt(key, expiration.getExpirationTimeInMilliseconds());
207207
}
@@ -213,7 +213,7 @@ default Boolean applyExpiration(byte @NonNull [] key,
213213
return expire(key, expiration.getExpirationTimeInSeconds());
214214
}
215215

216-
if (ObjectUtils.nullSafeEquals(TimeUnit.MILLISECONDS, expiration.getTimeUnit())) {
216+
if (expiration.isPrecise()) {
217217
if (expiration.isUnixTimestamp()) {
218218
return expireAt(key, expiration.getExpirationTimeInMilliseconds(), options.getCondition());
219219
}

src/main/java/org/springframework/data/redis/connection/jedis/JedisConverters.java

Lines changed: 62 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,11 @@
4444
import java.util.Map;
4545
import java.util.Set;
4646
import java.util.concurrent.TimeUnit;
47+
import java.util.function.LongFunction;
4748

4849
import org.jspecify.annotations.NonNull;
4950
import org.jspecify.annotations.Nullable;
51+
5052
import org.springframework.core.convert.converter.Converter;
5153
import org.springframework.data.domain.Sort;
5254
import org.springframework.data.geo.Distance;
@@ -358,13 +360,13 @@ public static SetParams toSetCommandExPxArgument(Expiration expiration, SetParam
358360
return paramsToUse;
359361
}
360362

361-
if (expiration.getTimeUnit() == TimeUnit.MILLISECONDS) {
362-
return expiration.isUnixTimestamp() ? paramsToUse.pxAt(expiration.getExpirationTime())
363-
: paramsToUse.px(expiration.getExpirationTime());
363+
ExpirationAdapter adapter = ExpirationAdapter.of(expiration);
364+
365+
if (adapter.isPrecise()) {
366+
return adapter.apply(paramsToUse::px, paramsToUse::pxAt);
364367
}
365368

366-
return expiration.isUnixTimestamp() ? paramsToUse.exAt(expiration.getConverted(TimeUnit.SECONDS))
367-
: paramsToUse.ex(expiration.getConverted(TimeUnit.SECONDS));
369+
return adapter.apply(paramsToUse::ex, paramsToUse::exAt);
368370
}
369371

370372
/**
@@ -390,15 +392,13 @@ static GetExParams toGetExParams(Expiration expiration, GetExParams params) {
390392
return params.persist();
391393
}
392394

393-
if (expiration.getTimeUnit() == TimeUnit.MILLISECONDS) {
394-
if (expiration.isUnixTimestamp()) {
395-
return params.pxAt(expiration.getExpirationTime());
396-
}
397-
return params.px(expiration.getExpirationTime());
395+
ExpirationAdapter adapter = ExpirationAdapter.of(expiration);
396+
397+
if (adapter.isPrecise()) {
398+
return adapter.apply(e -> params.px(e), a -> params.pxAt(a));
398399
}
399400

400-
return expiration.isUnixTimestamp() ? params.exAt(expiration.getConverted(TimeUnit.SECONDS))
401-
: params.ex(expiration.getConverted(TimeUnit.SECONDS));
401+
return adapter.apply(e -> params.ex(e), a -> params.exAt(a));
402402
}
403403

404404
/**
@@ -469,15 +469,13 @@ static HGetExParams toHGetExParams(@Nullable Expiration expiration) {
469469
return params.persist();
470470
}
471471

472-
if (expiration.getTimeUnit() == TimeUnit.MILLISECONDS) {
473-
return expiration.isUnixTimestamp() ?
474-
params.pxAt(expiration.getExpirationTime()) :
475-
params.px(expiration.getExpirationTime());
472+
ExpirationAdapter adapter = ExpirationAdapter.of(expiration);
473+
474+
if (adapter.isPrecise()) {
475+
return adapter.apply(e -> params.px(e), a -> params.pxAt(a));
476476
}
477477

478-
return expiration.isUnixTimestamp() ?
479-
params.exAt(expiration.getExpirationTimeInSeconds()) :
480-
params.ex(expiration.getExpirationTimeInSeconds());
478+
return adapter.apply(e -> params.ex(e), a -> params.exAt(a));
481479
}
482480

483481
/**
@@ -498,7 +496,7 @@ static HGetExParams toHGetExParams(@Nullable Expiration expiration) {
498496
* <dd>{@code EX|EXAT}</dd>
499497
* </dl>
500498
*
501-
* @param condition must not be {@literal null}; use {@code UPSERT} to omit FNX/FXX.
499+
* @param condition must not be {@literal null}; use {@code UPSERT} to omit FNX/FXX.
502500
* @param expiration can be {@literal null} to omit TTL.
503501
* @return never {@literal null}.
504502
* @since 4.0
@@ -521,17 +519,13 @@ static HSetExParams toHSetExParams(RedisHashCommands.@NonNull HashFieldSetOption
521519
return params.keepTtl();
522520
}
523521

524-
// PX | PXAT
525-
if (expiration.getTimeUnit() == TimeUnit.MILLISECONDS) {
526-
return expiration.isUnixTimestamp() ?
527-
params.pxAt(expiration.getExpirationTime()) :
528-
params.px(expiration.getExpirationTime());
522+
ExpirationAdapter adapter = ExpirationAdapter.of(expiration);
523+
524+
if (adapter.isPrecise()) {
525+
return adapter.apply(e -> params.px(e), a -> params.pxAt(a));
529526
}
530527

531-
// EX | EXAT
532-
return expiration.isUnixTimestamp() ?
533-
params.exAt(expiration.getExpirationTimeInSeconds()) :
534-
params.ex(expiration.getExpirationTimeInSeconds());
528+
return adapter.apply(e -> params.ex(e), a -> params.exAt(a));
535529
}
536530

537531
private static byte[] boundaryToBytes(org.springframework.data.domain.Range.Bound<?> boundary, byte[] inclPrefix,
@@ -939,4 +933,43 @@ public GeoResult<GeoLocation<byte[]>> convert(GeoRadiusResponse source) {
939933
}
940934
}
941935
}
936+
937+
/**
938+
* Adapter to apply {@link Expiration}.
939+
*/
940+
record ExpirationAdapter(Expiration expiration) {
941+
942+
ExpirationAdapter {
943+
Assert.isTrue(!expiration.isPersistent(), "Expiration does not define an expiry");
944+
}
945+
946+
/**
947+
* Create a new ExpirationAdapter.
948+
*
949+
* @param expiration
950+
* @return
951+
*/
952+
public static ExpirationAdapter of(Expiration expiration) {
953+
return new ExpirationAdapter(expiration);
954+
}
955+
956+
public boolean isPrecise() {
957+
return expiration.isPrecise();
958+
}
959+
960+
/**
961+
* Apply expiration to
962+
*
963+
* @param expire expiration mapping function.
964+
* @param expireAt expiration-at mapping function.
965+
*/
966+
public <T> T apply(LongFunction<T> expire, LongFunction<T> expireAt) {
967+
968+
long ttl = isPrecise() ? expiration.getExpirationTimeInMilliseconds() : expiration.getExpirationTimeInSeconds();
969+
970+
return expiration.isUnixTimestamp() ? expireAt.apply(ttl) : expire.apply(ttl);
971+
}
972+
973+
}
974+
942975
}

0 commit comments

Comments
 (0)