Skip to content

Commit

Permalink
Support NX|XX|CH|INCR options in ZADD #74
Browse files Browse the repository at this point in the history
  • Loading branch information
mp911de committed Jun 7, 2015
1 parent 5a2ea23 commit 42d9084
Show file tree
Hide file tree
Showing 6 changed files with 242 additions and 7 deletions.
22 changes: 18 additions & 4 deletions src/main/java/com/lambdaworks/redis/RedisAsyncConnectionImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -974,12 +974,27 @@ public RedisFuture<String> unwatch() {

@Override
public RedisFuture<Long> zadd(K key, double score, V member) {
return dispatch(commandBuilder.zadd(key, score, member));
return dispatch(commandBuilder.zadd(key, null, score, member));
}

@Override
public RedisFuture<Long> zadd(K key, Object... scoresAndValues) {
return dispatch(commandBuilder.zadd(key, scoresAndValues));
return dispatch(commandBuilder.zadd(key, null, scoresAndValues));
}

@Override
public RedisFuture<Long> zadd(K key, ZAddArgs zAddArgs, double score, V member) {
return dispatch(commandBuilder.zadd(key, zAddArgs, score, member));
}

@Override
public RedisFuture<Long> zadd(K key, ZAddArgs zAddArgs, Object... scoresAndValues) {
return dispatch(commandBuilder.zadd(key, zAddArgs, scoresAndValues));
}

@Override
public RedisFuture<Double> zaddincr(K key, double score, V member) {
return dispatch(commandBuilder.zaddincr(key, score, member));
}

@Override
Expand Down Expand Up @@ -1579,8 +1594,7 @@ protected <T> RedisCommand<K, V, T> dispatch(CommandType type, CommandOutput<K,
return dispatch(type, output, null);
}

protected <T> RedisCommand<K, V, T> dispatch(CommandType type, CommandOutput<K, V, T> output,
CommandArgs<K, V> args) {
protected <T> RedisCommand<K, V, T> dispatch(CommandType type, CommandOutput<K, V, T> output, CommandArgs<K, V> args) {
Command<K, V, T> cmd = new Command<K, V, T>(type, output, args, multi != null);
return dispatch(cmd);
}
Expand Down
40 changes: 37 additions & 3 deletions src/main/java/com/lambdaworks/redis/RedisCommandBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -943,17 +943,38 @@ public Command<K, V, String> unwatch() {
return createCommand(UNWATCH, new StatusOutput<K, V>(codec));
}

public Command<K, V, Long> zadd(K key, double score, V member) {
CommandArgs<K, V> args = new CommandArgs<K, V>(codec).addKey(key).add(score).addValue(member);
public Command<K, V, Long> zadd(K key, ZAddArgs zAddArgs, double score, V member) {
CommandArgs<K, V> args = new CommandArgs<K, V>(codec).addKey(key);

if (zAddArgs != null) {
zAddArgs.build(args);
}
args.add(score).addValue(member);

return createCommand(ZADD, new IntegerOutput<K, V>(codec), args);
}

public Command<K, V, Double> zaddincr(K key, double score, V member) {
CommandArgs<K, V> args = new CommandArgs<K, V>(codec).addKey(key);
args.add(INCR);
args.add(score).addValue(member);

return createCommand(ZADD, new DoubleOutput<K, V>(codec), args);
}

@SuppressWarnings("unchecked")
public Command<K, V, Long> zadd(K key, Object... scoresAndValues) {
public Command<K, V, Long> zadd(K key, ZAddArgs zAddArgs, Object... scoresAndValues) {
assertNotEmpty(scoresAndValues, "scoresAndValues " + MUST_NOT_BE_EMPTY);
assertNoNullElements(scoresAndValues, "scoresAndValues " + MUST_NOT_CONTAIN_NULL_ELEMENTS);
assertTrue(scoresAndValues.length % 2 == 0, "scoresAndValues.length must be a multiple of 2 and contain a "
+ "sequence of score1, value1, score2, value2, scoreN,valueN");

CommandArgs<K, V> args = new CommandArgs<K, V>(codec).addKey(key);

if (zAddArgs != null) {
zAddArgs.build(args);
}

for (int i = 0; i < scoresAndValues.length; i += 2) {
args.add((Double) scoresAndValues[i]);
args.addValue((V) scoresAndValues[i + 1]);
Expand Down Expand Up @@ -1686,4 +1707,17 @@ public static void assertNoNullElements(Object[] array, String message) {
}
}

/**
* Assert that {@code value} is {@literal true}.
*
* @param value the value to check
* @param message the exception message to use if the assertion fails
* @throws IllegalArgumentException if the object array contains a {@code null} element
*/
public static void assertTrue(boolean value, String message) {
if (!value) {
throw new IllegalArgumentException(message);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,47 @@ public interface RedisSortedSetsAsyncConnection<K, V> {
*/
RedisFuture<Long> zadd(K key, Object... scoresAndValues);

/**
* Add one or more members to a sorted set, or update its score if it already exists.
*
* @param key the key
* @param zAddArgs arguments for zadd
* @param score the score
* @param member the member
*
* @return RedisFuture&lt;Long&gt; integer-reply specifically:
*
* The number of elements added to the sorted sets, not including elements already existing for which the score was
* updated.
*/
RedisFuture<Long> zadd(K key, ZAddArgs zAddArgs, double score, V member);

/**
* Add one or more members to a sorted set, or update its score if it already exists.
*
* @param key the key
* @param zAddArgs arguments for zadd
* @param scoresAndValues the scoresAndValue tuples (score,value,score,value,...)
* @return RedisFuture&lt;Long&gt; integer-reply specifically:
*
* The number of elements added to the sorted sets, not including elements already existing for which the score was
* updated.
*/
RedisFuture<Long> zadd(K key, ZAddArgs zAddArgs, Object... scoresAndValues);

/**
* ZADD acts like ZINCRBY
*
* @param key the key
* @param score the score
* @param member the member
*
* @return RedisFuture&lt;Long&gt; integer-reply specifically:
*
* The total number of elements changed
*/
RedisFuture<Double> zaddincr(K key, double score, V member);

/**
* Get the number of members in a sorted set.
*
Expand Down
41 changes: 41 additions & 0 deletions src/main/java/com/lambdaworks/redis/RedisSortedSetsConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,47 @@ public interface RedisSortedSetsConnection<K, V> {
*/
Long zadd(K key, Object... scoresAndValues);

/**
* Add one or more members to a sorted set, or update its score if it already exists.
*
* @param key the key
* @param zAddArgs arguments for zadd
* @param score the score
* @param member the member
*
* @return Long integer-reply specifically:
*
* The number of elements added to the sorted sets, not including elements already existing for which the score was
* updated.
*/
Long zadd(K key, ZAddArgs zAddArgs, double score, V member);

/**
* Add one or more members to a sorted set, or update its score if it already exists.
*
* @param key the key
* @param zAddArgs arguments for zadd
* @param scoresAndValues the scoresAndValue tuples (score,value,score,value,...)
* @return Long integer-reply specifically:
*
* The number of elements added to the sorted sets, not including elements already existing for which the score was
* updated.
*/
Long zadd(K key, ZAddArgs zAddArgs, Object... scoresAndValues);

/**
* ZADD acts like ZINCRBY
*
* @param key the key
* @param score the score
* @param member the member
*
* @return Long integer-reply specifically:
*
* The total number of elements changed
*/
Double zaddincr(K key, double score, V member);

/**
* Get the number of members in a sorted set.
*
Expand Down
65 changes: 65 additions & 0 deletions src/main/java/com/lambdaworks/redis/ZAddArgs.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.lambdaworks.redis;

import com.lambdaworks.redis.protocol.CommandArgs;

/**
* Argument list builder for the improved redis <a href="http://redis.io/commands/zadd">ZADD</a> command starting from Redis
* 3.0.2. Static import the methods from {@link Builder} and call the methods: {@code xx()} or {@code nx()} .
*
* @author <a href="mailto:[email protected]">Mark Paluch</a>
*/
public class ZAddArgs {
private boolean nx = false;
private boolean xx = false;
private boolean ch = false;

public static class Builder {
/**
* Utility constructor.
*/
private Builder() {

}

public static ZAddArgs nx() {
return new ZAddArgs().nx();
}

public static ZAddArgs xx() {
return new ZAddArgs().xx();
}

public static ZAddArgs ch() {
return new ZAddArgs().ch();
}
}

private ZAddArgs nx() {
this.nx = true;
return this;
}

private ZAddArgs ch() {
this.ch = true;
return this;
}

private ZAddArgs xx() {
this.xx = true;
return this;
}

public <K, V> void build(CommandArgs<K, V> args) {
if (nx) {
args.add("NX");
}

if (xx) {
args.add("XX");
}

if (ch) {
args.add("CH");
}
}
}
40 changes: 40 additions & 0 deletions src/test/java/com/lambdaworks/redis/SortedSetCommandTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,46 @@ public void zadd() throws Exception {
assertEquals(list("a", "b", "c"), redis.zrange(key, 0, -1));
}

@Test
public void zaddnx() throws Exception {
assertEquals(1, (long) redis.zadd(key, 1.0, "a"));
assertEquals(0, (long) redis.zadd(key, ZAddArgs.Builder.nx(), 2.0, "a"));

assertEquals(1, (long) redis.zadd(key, ZAddArgs.Builder.nx(), 2.0, "b"));

assertEquals(svlist(sv(1.0, "a"), sv(2.0, "b")), redis.zrangeWithScores(key, 0, -1));
}

@Test
public void zaddxx() throws Exception {
assertEquals(1, (long) redis.zadd(key, 1.0, "a"));
assertEquals(0, (long) redis.zadd(key, ZAddArgs.Builder.xx(), 2.0, "a"));

assertEquals(0, (long) redis.zadd(key, ZAddArgs.Builder.xx(), 2.0, "b"));

assertEquals(svlist(sv(2.0, "a")), redis.zrangeWithScores(key, 0, -1));
}

@Test
public void zaddch() throws Exception {
assertEquals(1, (long) redis.zadd(key, 1.0, "a"));
assertEquals(1, (long) redis.zadd(key, ZAddArgs.Builder.ch(), 2.0, "a"));

assertEquals(1, (long) redis.zadd(key, ZAddArgs.Builder.ch(), 2.0, "b"));

assertEquals(svlist(sv(2.0, "a"), sv(2.0, "b")), redis.zrangeWithScores(key, 0, -1));
}

@Test
public void zaddincr() throws Exception {
assertEquals(1, redis.zadd(key, 1.0, "a").longValue());
assertEquals(3, redis.zaddincr(key, 2.0, "a").longValue());

assertEquals(2, redis.zaddincr(key, 2.0, "b").longValue());

assertEquals(svlist(sv(2.0, "b"), sv(3.0, "a")), redis.zrangeWithScores(key, 0, -1));
}

@Test
public void zcard() throws Exception {
assertEquals(0, (long) redis.zcard(key));
Expand Down

0 comments on commit 42d9084

Please sign in to comment.