Skip to content

Commit

Permalink
Implement HPEXPIRE, HPEXPIREAT, HPEXPIRETIME, HTTL and HPTTL (#2857)
Browse files Browse the repository at this point in the history
* Fixes to the hash field expiration functions

* Implemented HPEXPIRE, HPEXPIREAT, HPEXPIRETIME, HTTL, HPTTL

* Format the files

* FIELDS keyword was introduced as per the PRD

* Extend tests to include HTTL

* Repair unit tests, add new ones for the new commands

* Disable failing test, becasue it is very unstable

* Modify return value to list of long values, fix cluster logic

* Polishing

* Polishing - addressed Ali's comments

* Polishing: Modified by mistake

* Polishing : Addressed Marks' comments
  • Loading branch information
tishun committed May 22, 2024
1 parent 35bfcf1 commit 27dbd4b
Show file tree
Hide file tree
Showing 18 changed files with 2,252 additions and 439 deletions.
92 changes: 80 additions & 12 deletions src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -799,26 +799,94 @@ public RedisFuture<Boolean> expire(K key, Duration seconds, ExpireArgs expireArg
}

@Override
public RedisFuture<Boolean> hexpire(K key, long seconds, K... fields) {
public RedisFuture<List<Long>> hexpire(K key, long seconds, K... fields) {
return hexpire(key, seconds, null, fields);
}

@Override
public RedisFuture<Boolean> hexpire(K key, long seconds, ExpireArgs expireArgs, K... fields) {
public RedisFuture<List<Long>> hexpire(K key, long seconds, ExpireArgs expireArgs, K... fields) {
return dispatch(commandBuilder.hexpire(key, seconds, expireArgs, fields));
}

@Override
public RedisFuture<Boolean> hexpire(K key, Duration seconds, K... fields) {
public RedisFuture<List<Long>> hexpire(K key, Duration seconds, K... fields) {
return hexpire(key, seconds, null, fields);
}

@Override
public RedisFuture<Boolean> hexpire(K key, Duration seconds, ExpireArgs expireArgs, K... fields) {
public RedisFuture<List<Long>> hexpire(K key, Duration seconds, ExpireArgs expireArgs, K... fields) {
LettuceAssert.notNull(seconds, "Timeout must not be null");
return hexpire(key, seconds.toMillis() / 1000, expireArgs, fields);
}

@Override
public RedisFuture<List<Long>> httl(K key, K... fields) {
return dispatch(commandBuilder.httl(key, fields));
}

@Override
public RedisFuture<List<Long>> hpexpire(K key, long milliseconds, K... fields) {
return hpexpire(key, milliseconds, null, fields);
}

@Override
public RedisFuture<List<Long>> hpexpire(K key, long milliseconds, ExpireArgs expireArgs, K... fields) {
return dispatch(commandBuilder.hpexpire(key, milliseconds, expireArgs, fields));
}

@Override
public RedisFuture<List<Long>> hpexpire(K key, Duration milliseconds, K... fields) {
return hpexpire(key, milliseconds, null, fields);
}

@Override
public RedisFuture<List<Long>> hpexpire(K key, Duration milliseconds, ExpireArgs expireArgs, K... fields) {
LettuceAssert.notNull(milliseconds, "Timeout must not be null");
return hpexpire(key, milliseconds.toMillis(), expireArgs, fields);
}

@Override
public RedisFuture<List<Long>> hpexpireat(K key, Date timestamp, K... fields) {
return hpexpireat(key, timestamp, null, fields);
}

@Override
public RedisFuture<List<Long>> hpexpireat(K key, Date timestamp, ExpireArgs expireArgs, K... fields) {
LettuceAssert.notNull(timestamp, "Timestamp must not be null");
return hpexpireat(key, timestamp.getTime(), expireArgs, fields);
}

@Override
public RedisFuture<List<Long>> hpexpireat(K key, Instant timestamp, K... fields) {
return hpexpireat(key, timestamp, null, fields);
}

@Override
public RedisFuture<List<Long>> hpexpireat(K key, Instant timestamp, ExpireArgs expireArgs, K... fields) {
LettuceAssert.notNull(timestamp, "Timestamp must not be null");
return hpexpireat(key, timestamp.toEpochMilli(), expireArgs, fields);
}

@Override
public RedisFuture<List<Long>> hpexpireat(K key, long timestamp, K... fields) {
return hpexpireat(key, timestamp, null, fields);
}

@Override
public RedisFuture<List<Long>> hpexpireat(K key, long timestamp, ExpireArgs expireArgs, K... fields) {
return dispatch(commandBuilder.hpexpireat(key, timestamp, expireArgs, fields));
}

@Override
public RedisFuture<List<Long>> hpexpiretime(K key, K... fields) {
return dispatch(commandBuilder.hpexpiretime(key, fields));
}

@Override
public RedisFuture<List<Long>> hpttl(K key, K... fields) {
return dispatch(commandBuilder.hpttl(key, fields));
}

@Override
public RedisFuture<Boolean> expireat(K key, long timestamp) {
return expireat(key, timestamp, null);
Expand Down Expand Up @@ -852,34 +920,34 @@ public RedisFuture<Boolean> expireat(K key, Instant timestamp, ExpireArgs expire
}

@Override
public RedisFuture<Boolean> hexpireat(K key, long timestamp, K... fields) {
public RedisFuture<List<Long>> hexpireat(K key, long timestamp, K... fields) {
return hexpireat(key, timestamp, null, fields);
}

@Override
public RedisFuture<Boolean> hexpireat(K key, long timestamp, ExpireArgs expireArgs, K... fields) {
public RedisFuture<List<Long>> hexpireat(K key, long timestamp, ExpireArgs expireArgs, K... fields) {
return dispatch(commandBuilder.hexpireat(key, timestamp, expireArgs, fields));

}

@Override
public RedisFuture<Boolean> hexpireat(K key, Date timestamp, K... fields) {
public RedisFuture<List<Long>> hexpireat(K key, Date timestamp, K... fields) {
return hexpireat(key, timestamp, null, fields);
}

@Override
public RedisFuture<Boolean> hexpireat(K key, Date timestamp, ExpireArgs expireArgs, K... fields) {
public RedisFuture<List<Long>> hexpireat(K key, Date timestamp, ExpireArgs expireArgs, K... fields) {
LettuceAssert.notNull(timestamp, "Timestamp must not be null");
return hexpireat(key, timestamp.getTime() / 1000, expireArgs, fields);
}

@Override
public RedisFuture<Boolean> hexpireat(K key, Instant timestamp, K... fields) {
public RedisFuture<List<Long>> hexpireat(K key, Instant timestamp, K... fields) {
return hexpireat(key, timestamp, null, fields);
}

@Override
public RedisFuture<Boolean> hexpireat(K key, Instant timestamp, ExpireArgs expireArgs, K... fields) {
public RedisFuture<List<Long>> hexpireat(K key, Instant timestamp, ExpireArgs expireArgs, K... fields) {
LettuceAssert.notNull(timestamp, "Timestamp must not be null");
return hexpireat(key, timestamp.toEpochMilli() / 1000, expireArgs, fields);
}
Expand All @@ -890,7 +958,7 @@ public RedisFuture<Long> expiretime(K key) {
}

@Override
public RedisFuture<Long> hexpiretime(K key, K... fields) {
public RedisFuture<List<Long>> hexpiretime(K key, K... fields) {
return dispatch(commandBuilder.hexpiretime(key, fields));
}

Expand Down Expand Up @@ -1553,7 +1621,7 @@ public RedisFuture<Boolean> persist(K key) {
}

@Override
public RedisFuture<Boolean> hpersist(K key, K... fields) {
public RedisFuture<List<Long>> hpersist(K key, K... fields) {
return dispatch(commandBuilder.hpersist(key, fields));
}

Expand Down
100 changes: 84 additions & 16 deletions src/main/java/io/lettuce/core/AbstractRedisReactiveCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -859,22 +859,22 @@ public Mono<Boolean> expire(K key, Duration seconds, ExpireArgs expireArgs) {
}

@Override
public Mono<Boolean> hexpire(K key, long seconds, K... fields) {
public Flux<Long> hexpire(K key, long seconds, K... fields) {
return hexpire(key, seconds, null, fields);
}

@Override
public Mono<Boolean> hexpire(K key, long seconds, ExpireArgs expireArgs, K... fields) {
return createMono(() -> commandBuilder.hexpire(key, seconds, expireArgs, fields));
public Flux<Long> hexpire(K key, long seconds, ExpireArgs expireArgs, K... fields) {
return createDissolvingFlux(() -> commandBuilder.hexpire(key, seconds, expireArgs, fields));
}

@Override
public Mono<Boolean> hexpire(K key, Duration seconds, K... fields) {
public Flux<Long> hexpire(K key, Duration seconds, K... fields) {
return hexpire(key, seconds, null, fields);
}

@Override
public Mono<Boolean> hexpire(K key, Duration seconds, ExpireArgs expireArgs, K... fields) {
public Flux<Long> hexpire(K key, Duration seconds, ExpireArgs expireArgs, K... fields) {
LettuceAssert.notNull(seconds, "Timeout must not be null");
return hexpire(key, seconds.toMillis() / 1000, expireArgs, fields);
}
Expand Down Expand Up @@ -912,33 +912,33 @@ public Mono<Boolean> expireat(K key, Instant timestamp, ExpireArgs expireArgs) {
}

@Override
public Mono<Boolean> hexpireat(K key, long timestamp, K... fields) {
public Flux<Long> hexpireat(K key, long timestamp, K... fields) {
return hexpireat(key, timestamp, null, fields);
}

@Override
public Mono<Boolean> hexpireat(K key, long timestamp, ExpireArgs expireArgs, K... fields) {
return createMono(() -> commandBuilder.hexpireat(key, timestamp, expireArgs, fields));
public Flux<Long> hexpireat(K key, long timestamp, ExpireArgs expireArgs, K... fields) {
return createDissolvingFlux(() -> commandBuilder.hexpireat(key, timestamp, expireArgs, fields));
}

@Override
public Mono<Boolean> hexpireat(K key, Date timestamp, K... fields) {
public Flux<Long> hexpireat(K key, Date timestamp, K... fields) {
return hexpireat(key, timestamp, null, fields);
}

@Override
public Mono<Boolean> hexpireat(K key, Date timestamp, ExpireArgs expireArgs, K... fields) {
public Flux<Long> hexpireat(K key, Date timestamp, ExpireArgs expireArgs, K... fields) {
LettuceAssert.notNull(timestamp, "Timestamp must not be null");
return hexpireat(key, timestamp.getTime() / 1000, expireArgs, fields);
}

@Override
public Mono<Boolean> hexpireat(K key, Instant timestamp, K... fields) {
public Flux<Long> hexpireat(K key, Instant timestamp, K... fields) {
return hexpireat(key, timestamp, null, fields);
}

@Override
public Mono<Boolean> hexpireat(K key, Instant timestamp, ExpireArgs expireArgs, K... fields) {
public Flux<Long> hexpireat(K key, Instant timestamp, ExpireArgs expireArgs, K... fields) {
LettuceAssert.notNull(timestamp, "Timestamp must not be null");
return hexpireat(key, timestamp.toEpochMilli() / 1000, expireArgs, fields);
}
Expand All @@ -949,8 +949,76 @@ public Mono<Long> expiretime(K key) {
}

@Override
public Mono<Long> hexpiretime(K key, K... fields) {
return createMono(() -> commandBuilder.hexpiretime(key, fields));
public Flux<Long> hexpiretime(K key, K... fields) {
return createDissolvingFlux(() -> commandBuilder.hexpiretime(key, fields));
}

@Override
public Flux<Long> httl(K key, K... fields) {
return createDissolvingFlux(() -> commandBuilder.httl(key, fields));
}

@Override
public Flux<Long> hpexpire(K key, long milliseconds, K... fields) {
return hpexpire(key, milliseconds, null, fields);
}

@Override
public Flux<Long> hpexpire(K key, long milliseconds, ExpireArgs expireArgs, K... fields) {
return createDissolvingFlux(() -> commandBuilder.hpexpire(key, milliseconds, expireArgs, fields));
}

@Override
public Flux<Long> hpexpire(K key, Duration milliseconds, K... fields) {
return hpexpire(key, milliseconds, null, fields);
}

@Override
public Flux<Long> hpexpire(K key, Duration milliseconds, ExpireArgs expireArgs, K... fields) {
LettuceAssert.notNull(milliseconds, "Timeout must not be null");
return hpexpire(key, milliseconds.toMillis(), expireArgs, fields);
}

@Override
public Flux<Long> hpexpireat(K key, Date timestamp, K... fields) {
return hpexpireat(key, timestamp, null, fields);
}

@Override
public Flux<Long> hpexpireat(K key, Date timestamp, ExpireArgs expireArgs, K... fields) {
LettuceAssert.notNull(timestamp, "Timestamp must not be null");
return hpexpireat(key, timestamp.getTime(), expireArgs, fields);
}

@Override
public Flux<Long> hpexpireat(K key, Instant timestamp, K... fields) {
return hpexpireat(key, timestamp, null, fields);
}

@Override
public Flux<Long> hpexpireat(K key, Instant timestamp, ExpireArgs expireArgs, K... fields) {
LettuceAssert.notNull(timestamp, "Timestamp must not be null");
return hpexpireat(key, timestamp.toEpochMilli(), expireArgs, fields);
}

@Override
public Flux<Long> hpexpireat(K key, long timestamp, K... fields) {
return hpexpireat(key, timestamp, null, fields);
}

@Override
public Flux<Long> hpexpireat(K key, long timestamp, ExpireArgs expireArgs, K... fields) {
return createDissolvingFlux(() -> commandBuilder.hpexpireat(key, timestamp, expireArgs, fields));
}

@Override
public Flux<Long> hpexpiretime(K key, K... fields) {
return createDissolvingFlux(() -> commandBuilder.hpexpiretime(key, fields));
}

@Override
public Flux<Long> hpttl(K key, K... fields) {
return createDissolvingFlux(() -> commandBuilder.hpttl(key, fields));
}

@Override
Expand Down Expand Up @@ -1619,8 +1687,8 @@ public Mono<Boolean> persist(K key) {
}

@Override
public Mono<Boolean> hpersist(K key, K... fields) {
return createMono(() -> commandBuilder.hpersist(key, fields));
public Flux<Long> hpersist(K key, K... fields) {
return createDissolvingFlux(() -> commandBuilder.hpersist(key, fields));
}

@Override
Expand Down
Loading

0 comments on commit 27dbd4b

Please sign in to comment.