Skip to content

Commit

Permalink
LMOVE/BLMOVE commands introduced #1448
Browse files Browse the repository at this point in the history
Original pull request: #1488.
  • Loading branch information
sokomishalov authored and mp911de committed Nov 7, 2020
1 parent a48f117 commit 455876c
Show file tree
Hide file tree
Showing 15 changed files with 401 additions and 6 deletions.
10 changes: 10 additions & 0 deletions src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,11 @@ public RedisFuture<Long> bitpos(K key, boolean state, long start, long end) {
return dispatch(commandBuilder.bitpos(key, state, start, end));
}

@Override
public RedisFuture<V> blmove(K source, K destination, LMoveArgs args, long timeout) {
return dispatch(commandBuilder.blmove(source, destination, args, timeout));
}

@Override
public RedisFuture<KeyValue<K, V>> blpop(long timeout, K... keys) {
return dispatch(commandBuilder.blpop(timeout, keys));
Expand Down Expand Up @@ -917,6 +922,11 @@ public RedisFuture<Long> llen(K key) {
return dispatch(commandBuilder.llen(key));
}

@Override
public RedisFuture<V> lmove(K source, K destination, LMoveArgs args) {
return dispatch(commandBuilder.lmove(source, destination, args));
}

@Override
public RedisFuture<V> lpop(K key) {
return dispatch(commandBuilder.lpop(key));
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/io/lettuce/core/AbstractRedisReactiveCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,11 @@ public Mono<Long> bitpos(K key, boolean state, long start, long end) {
return createMono(() -> commandBuilder.bitpos(key, state, start, end));
}

@Override
public Mono<V> blmove(K source, K destination, LMoveArgs args, long timeout) {
return createMono(() -> commandBuilder.blmove(source, destination, args, timeout));
}

@Override
public Mono<KeyValue<K, V>> blpop(long timeout, K... keys) {
return createMono(() -> commandBuilder.blpop(timeout, keys));
Expand Down Expand Up @@ -976,6 +981,11 @@ public Mono<Long> llen(K key) {
return createMono(() -> commandBuilder.llen(key));
}

@Override
public Mono<V> lmove(K source, K destination, LMoveArgs args) {
return createMono(() -> commandBuilder.lmove(source, destination, args));
}

@Override
public Mono<V> lpop(K key) {
return createMono(() -> commandBuilder.lpop(key));
Expand Down
111 changes: 111 additions & 0 deletions src/main/java/io/lettuce/core/LMoveArgs.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.lettuce.core;

import io.lettuce.core.protocol.CommandArgs;

import static io.lettuce.core.protocol.CommandKeyword.LEFT;
import static io.lettuce.core.protocol.CommandKeyword.RIGHT;

/**
* Argument list builder for the Redis <a href="http://redis.io/commands/blmove">BLMOVE</a> and
* <a href="http://redis.io/commands/lmove">LMOVE</a> commands. Static import the methods from {@link Builder} and
* chain the method calls: {@code leftRight()}.
*
* @author Mikhael Sokolov
* @since 6.1
*/
public class LMoveArgs implements CompositeArgument {

private enum Direction {
LEFT, RIGHT
}

private final Direction source;

private final Direction destination;

private LMoveArgs(Direction source, Direction destination) {
this.source = source;
this.destination = destination;
}

/**
* Builder entry points for {@link LMoveArgs}.
*/
public static class Builder {

/**
* Utility constructor.
*/
private Builder() {
}

/**
* Creates new {@link LMoveArgs} setting with LEFT LEFT directions.
*
* @return new {@link LMoveArgs} with args set.
*/
public static LMoveArgs leftLeft() {
return new LMoveArgs(Direction.LEFT, Direction.LEFT);
}

/**
* Creates new {@link LMoveArgs} setting with LEFT RIGHT directions.
*
* @return new {@link LMoveArgs} with args set.
*/
public static LMoveArgs leftRight() {
return new LMoveArgs(Direction.LEFT, Direction.RIGHT);
}

/**
* Creates new {@link LMoveArgs} setting with RIGHT LEFT directions.
*
* @return new {@link LMoveArgs} with args set.
*/
public static LMoveArgs rightLeft() {
return new LMoveArgs(Direction.RIGHT, Direction.LEFT);
}

/**
* Creates new {@link LMoveArgs} setting with RIGHT RIGHT directions.
*
* @return new {@link LMoveArgs} with args set.
*/
public static LMoveArgs rightRight() {
return new LMoveArgs(Direction.RIGHT, Direction.RIGHT);
}
}

public <K, V> void build(CommandArgs<K, V> args) {
passDirection(source, args);
passDirection(destination, args);
}

private static <K, V> void passDirection(Direction direction, CommandArgs<K, V> args) {
switch (direction) {
case LEFT:
args.add(LEFT);
break;
case RIGHT:
args.add(RIGHT);
break;
default:
throw new IllegalArgumentException(String.format("Direction %s not supported", direction));
}
}
}
23 changes: 23 additions & 0 deletions src/main/java/io/lettuce/core/RedisCommandBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,18 @@ Command<K, V, Long> bitpos(K key, boolean state, long start, long end) {
return createCommand(BITPOS, new IntegerOutput<>(codec), args);
}

Command<K, V, V> blmove(K source, K destination, LMoveArgs lMoveArgs, long timeout) {
LettuceAssert.notNull(source, "Source " + MUST_NOT_BE_NULL);
LettuceAssert.notNull(destination, "Destination " + MUST_NOT_BE_NULL);
LettuceAssert.notNull(lMoveArgs, "LMoveArgs " + MUST_NOT_BE_NULL);

CommandArgs<K, V> args = new CommandArgs<>(codec);
args.addKey(source).addKey(destination);
lMoveArgs.build(args);
args.add(timeout);
return createCommand(BLMOVE, new ValueOutput<>(codec), args);
}

Command<K, V, KeyValue<K, V>> blpop(long timeout, K... keys) {
notEmpty(keys);

Expand Down Expand Up @@ -1224,6 +1236,17 @@ Command<K, V, Long> llen(K key) {
return createCommand(LLEN, new IntegerOutput<>(codec), key);
}

Command<K, V, V> lmove(K source, K destination, LMoveArgs lMoveArgs) {
LettuceAssert.notNull(source, "Source " + MUST_NOT_BE_NULL);
LettuceAssert.notNull(destination, "Destination " + MUST_NOT_BE_NULL);
LettuceAssert.notNull(lMoveArgs, "LMoveArgs " + MUST_NOT_BE_NULL);

CommandArgs<K, V> args = new CommandArgs<>(codec);
args.addKey(source).addKey(destination);
lMoveArgs.build(args);
return createCommand(LMOVE, new ValueOutput<>(codec), args);
}

Command<K, V, V> lpop(K key) {
notNullKey(key);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.util.List;
import io.lettuce.core.KeyValue;
import io.lettuce.core.LPosArgs;
import io.lettuce.core.LMoveArgs;
import io.lettuce.core.output.ValueStreamingChannel;
import io.lettuce.core.RedisFuture;

Expand All @@ -32,6 +33,22 @@
*/
public interface RedisListAsyncCommands<K, V> {

/**
* Atomically returns and removes the first/last element (head/tail depending on the
* wherefrom argument) of the list stored at source, and pushes the element at the
* first/last element (head/tail depending on the whereto argument) of the list stored at destination.
* When source is empty, Redis will block the connection until another client pushes to it
* or until timeout is reached.
*
* @param source the source key.
* @param destination the destination type: key.
* @param args command arguments to configure source and destination directions.
* @param timeout the timeout in seconds.
* @return V bulk-string-reply the element being popped and pushed.
* @since 6.1
*/
RedisFuture<V> blmove(K source, K destination, LMoveArgs args, long timeout);

/**
* Remove and get the first element in a list, or block until one is available.
*
Expand Down Expand Up @@ -98,6 +115,19 @@ public interface RedisListAsyncCommands<K, V> {
*/
RedisFuture<Long> llen(K key);

/**
* Atomically returns and removes the first/last element (head/tail depending on the
* wherefrom argument) of the list stored at source, and pushes the element at the
* first/last element (head/tail depending on the whereto argument) of the list stored at destination.
*
* @param source the source key.
* @param destination the destination type: key.
* @param args command arguments to configure source and destination directions.
* @return V bulk-string-reply the element being popped and pushed.
* @since 6.1
*/
RedisFuture<V> lmove(K source, K destination, LMoveArgs args);

/**
* Remove and get the first element in a list.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import reactor.core.publisher.Mono;
import io.lettuce.core.KeyValue;
import io.lettuce.core.LPosArgs;
import io.lettuce.core.LMoveArgs;
import io.lettuce.core.output.ValueStreamingChannel;

/**
Expand All @@ -32,6 +33,22 @@
*/
public interface RedisListReactiveCommands<K, V> {

/**
* Atomically returns and removes the first/last element (head/tail depending on the
* wherefrom argument) of the list stored at source, and pushes the element at the
* first/last element (head/tail depending on the whereto argument) of the list stored at destination.
* When source is empty, Redis will block the connection until another client pushes to it
* or until timeout is reached.
*
* @param source the source key.
* @param destination the destination type: key.
* @param args command arguments to configure source and destination directions.
* @param timeout the timeout in seconds.
* @return V bulk-string-reply the element being popped and pushed.
* @since 6.1
*/
Mono<V> blmove(K source, K destination, LMoveArgs args, long timeout);

/**
* Remove and get the first element in a list, or block until one is available.
*
Expand Down Expand Up @@ -98,6 +115,19 @@ public interface RedisListReactiveCommands<K, V> {
*/
Mono<Long> llen(K key);

/**
* Atomically returns and removes the first/last element (head/tail depending on the
* wherefrom argument) of the list stored at source, and pushes the element at the
* first/last element (head/tail depending on the whereto argument) of the list stored at destination.
*
* @param source the source key.
* @param destination the destination type: key.
* @param args command arguments to configure source and destination directions.
* @return V bulk-string-reply the element being popped and pushed.
* @since 6.1
*/
Mono<V> lmove(K source, K destination, LMoveArgs args);

/**
* Remove and get the first element in a list.
*
Expand Down
30 changes: 30 additions & 0 deletions src/main/java/io/lettuce/core/api/sync/RedisListCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.util.List;
import io.lettuce.core.KeyValue;
import io.lettuce.core.LPosArgs;
import io.lettuce.core.LMoveArgs;
import io.lettuce.core.output.ValueStreamingChannel;

/**
Expand All @@ -31,6 +32,22 @@
*/
public interface RedisListCommands<K, V> {

/**
* Atomically returns and removes the first/last element (head/tail depending on the
* wherefrom argument) of the list stored at source, and pushes the element at the
* first/last element (head/tail depending on the whereto argument) of the list stored at destination.
* When source is empty, Redis will block the connection until another client pushes to it
* or until timeout is reached.
*
* @param source the source key.
* @param destination the destination type: key.
* @param args command arguments to configure source and destination directions.
* @param timeout the timeout in seconds.
* @return V bulk-string-reply the element being popped and pushed.
* @since 6.1
*/
V blmove(K source, K destination, LMoveArgs args, long timeout);

/**
* Remove and get the first element in a list, or block until one is available.
*
Expand Down Expand Up @@ -97,6 +114,19 @@ public interface RedisListCommands<K, V> {
*/
Long llen(K key);

/**
* Atomically returns and removes the first/last element (head/tail depending on the
* wherefrom argument) of the list stored at source, and pushes the element at the
* first/last element (head/tail depending on the whereto argument) of the list stored at destination.
*
* @param source the source key.
* @param destination the destination type: key.
* @param args command arguments to configure source and destination directions.
* @return V bulk-string-reply the element being popped and pushed.
* @since 6.1
*/
V lmove(K source, K destination, LMoveArgs args);

/**
* Remove and get the first element in a list.
*
Expand Down
Loading

0 comments on commit 455876c

Please sign in to comment.