DATAREDIS-352 - Enhance range options for ZSET.

We now allow usage of Range and Limit types (newly introduced for ZRANGEBYLEX) on mostly all ZSET range operations.
Extracted constants for plus/minus and -inf/+inf expressions.

Original pull request: #138.
This commit is contained in:
Christoph Strobl
2015-04-20 12:04:59 +02:00
committed by Thomas Darimont
parent 3d4f62f5b7
commit 283a9638f2
11 changed files with 1094 additions and 215 deletions

View File

@@ -972,6 +972,20 @@ public class DefaultStringRedisConnection implements StringRedisConnection {
return result;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zCount(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range)
*/
@Override
public Long zCount(byte[] key, Range range) {
Long result = delegate.zCount(key, range);
if (isFutureConversion()) {
addResultConverter(identityConverter);
}
return result;
}
public Double zIncrBy(byte[] key, double increment, byte[] value) {
Double result = delegate.zIncrBy(key, increment, value);
if (isFutureConversion()) {
@@ -1012,6 +1026,48 @@ public class DefaultStringRedisConnection implements StringRedisConnection {
return results;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByScore(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range)
*/
@Override
public Set<byte[]> zRangeByScore(byte[] key, Range range) {
Set<byte[]> results = delegate.zRangeByScore(key, range);
if (isFutureConversion()) {
addResultConverter(identityConverter);
}
return results;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByScore(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range, org.springframework.data.redis.connection.RedisZSetCommands.Limit)
*/
@Override
public Set<byte[]> zRangeByScore(byte[] key, Range range, Limit limit) {
Set<byte[]> results = delegate.zRangeByScore(key, range, limit);
if (isFutureConversion()) {
addResultConverter(identityConverter);
}
return results;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByScoreWithScores(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range)
*/
@Override
public Set<Tuple> zRangeByScoreWithScores(byte[] key, Range range) {
Set<Tuple> results = delegate.zRangeByScoreWithScores(key, range);
if (isFutureConversion()) {
addResultConverter(identityConverter);
}
return results;
}
public Set<byte[]> zRangeByScore(byte[] key, double min, double max) {
Set<byte[]> results = delegate.zRangeByScore(key, min, max);
if (isFutureConversion()) {
@@ -1028,6 +1084,20 @@ public class DefaultStringRedisConnection implements StringRedisConnection {
return results;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByScoreWithScores(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range, org.springframework.data.redis.connection.RedisZSetCommands.Limit)
*/
@Override
public Set<Tuple> zRangeByScoreWithScores(byte[] key, Range range, Limit limit) {
Set<Tuple> results = delegate.zRangeByScoreWithScores(key, range, limit);
if (isFutureConversion()) {
addResultConverter(identityConverter);
}
return results;
}
public Set<Tuple> zRangeByScoreWithScores(byte[] key, double min, double max) {
Set<Tuple> results = delegate.zRangeByScoreWithScores(key, min, max);
if (isFutureConversion()) {
@@ -1052,6 +1122,20 @@ public class DefaultStringRedisConnection implements StringRedisConnection {
return results;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByScore(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range)
*/
@Override
public Set<byte[]> zRevRangeByScore(byte[] key, Range range) {
Set<byte[]> results = delegate.zRevRangeByScore(key, range);
if (isFutureConversion()) {
addResultConverter(identityConverter);
}
return results;
}
public Set<byte[]> zRevRangeByScore(byte[] key, double min, double max) {
Set<byte[]> results = delegate.zRevRangeByScore(key, min, max);
if (isFutureConversion()) {
@@ -1060,6 +1144,20 @@ public class DefaultStringRedisConnection implements StringRedisConnection {
return results;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByScore(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range, org.springframework.data.redis.connection.RedisZSetCommands.Limit)
*/
@Override
public Set<byte[]> zRevRangeByScore(byte[] key, Range range, Limit limit) {
Set<byte[]> results = delegate.zRevRangeByScore(key, range, limit);
if (isFutureConversion()) {
addResultConverter(identityConverter);
}
return results;
}
public Set<Tuple> zRevRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count) {
Set<Tuple> results = delegate.zRevRangeByScoreWithScores(key, min, max, offset, count);
if (isFutureConversion()) {
@@ -1068,6 +1166,34 @@ public class DefaultStringRedisConnection implements StringRedisConnection {
return results;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByScoreWithScores(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range)
*/
@Override
public Set<Tuple> zRevRangeByScoreWithScores(byte[] key, Range range) {
Set<Tuple> results = delegate.zRevRangeByScoreWithScores(key, range);
if (isFutureConversion()) {
addResultConverter(identityConverter);
}
return results;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByScoreWithScores(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range, org.springframework.data.redis.connection.RedisZSetCommands.Limit)
*/
@Override
public Set<Tuple> zRevRangeByScoreWithScores(byte[] key, Range range, Limit limit) {
Set<Tuple> results = delegate.zRevRangeByScoreWithScores(key, range, limit);
if (isFutureConversion()) {
addResultConverter(identityConverter);
}
return results;
}
public Set<Tuple> zRevRangeByScoreWithScores(byte[] key, double min, double max) {
Set<Tuple> results = delegate.zRevRangeByScoreWithScores(key, min, max);
if (isFutureConversion()) {
@@ -1108,6 +1234,15 @@ public class DefaultStringRedisConnection implements StringRedisConnection {
return result;
}
@Override
public Long zRemRangeByScore(byte[] key, Range range) {
Long result = delegate.zRemRangeByScore(key, range);
if (isFutureConversion()) {
addResultConverter(identityConverter);
}
return result;
}
public Set<byte[]> zRevRange(byte[] key, long start, long end) {
Set<byte[]> results = delegate.zRevRange(key, start, end);
if (isFutureConversion()) {

View File

@@ -309,6 +309,16 @@ public interface RedisZSetCommands {
*/
Set<byte[]> zRangeByScore(byte[] key, double min, double max);
/**
* Get set of {@link Tuple}s where score is between {@code Range#min} and {@code Range#max} from sorted set.
*
* @param key
* @param range
* @return
* @since 1.6
*/
Set<Tuple> zRangeByScoreWithScores(byte[] key, Range range);
/**
* Get set of {@link Tuple}s where score is between {@code min} and {@code max} from sorted set.
* <p>
@@ -351,6 +361,18 @@ public interface RedisZSetCommands {
*/
Set<Tuple> zRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count);
/**
* Get set of {@link Tuple}s in range from {@code Limit#offset} to {@code Limit#offset + Limit#count} where score is
* between {@code Range#min} and {@code Range#max} from sorted set.
*
* @param key
* @param range
* @param limit
* @return
* @since 1.6
*/
Set<Tuple> zRangeByScoreWithScores(byte[] key, Range range, Limit limit);
/**
* Get elements in range from {@code begin} to {@code end} from sorted set ordered from high to low.
* <p>
@@ -387,6 +409,17 @@ public interface RedisZSetCommands {
*/
Set<byte[]> zRevRangeByScore(byte[] key, double min, double max);
/**
* Get elements where score is between {@code Range#min} and {@code Range#max} from sorted set ordered from high to
* low.
*
* @param key
* @param range
* @return
* @since 1.6
*/
Set<byte[]> zRevRangeByScore(byte[] key, Range range);
/**
* Get set of {@link Tuple} where score is between {@code min} and {@code max} from sorted set ordered from high to
* low.
@@ -415,6 +448,18 @@ public interface RedisZSetCommands {
*/
Set<byte[]> zRevRangeByScore(byte[] key, double min, double max, long offset, long count);
/**
* Get elements in range from {@code Limit#offset} to {@code Limit#offset + Limit#count} where score is between
* {@code Range#min} and {@code Range#max} from sorted set ordered high -> low.
*
* @param key
* @param range
* @param limit
* @return
* @since 1.6
*/
Set<byte[]> zRevRangeByScore(byte[] key, Range range, Limit limit);
/**
* Get set of {@link Tuple} in range from {@code begin} to {@code end} where score is between {@code min} and
* {@code max} from sorted set ordered high -> low.
@@ -430,6 +475,29 @@ public interface RedisZSetCommands {
*/
Set<Tuple> zRevRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count);
/**
* Get set of {@link Tuple} where score is between {@code Range#min} and {@code Range#max} from sorted set ordered
* from high to low.
*
* @param key
* @param range
* @return
* @since 1.6
*/
Set<Tuple> zRevRangeByScoreWithScores(byte[] key, Range range);
/**
* Get set of {@link Tuple} in range from {@code Limit#offset} to {@code Limit#count} where score is between
* {@code Range#min} and {@code Range#max} from sorted set ordered high -> low.
*
* @param key
* @param range
* @param limit
* @return
* @since 1.6
*/
Set<Tuple> zRevRangeByScoreWithScores(byte[] key, Range range, Limit limit);
/**
* Count number of elements within sorted set with scores between {@code min} and {@code max}.
* <p>
@@ -442,6 +510,17 @@ public interface RedisZSetCommands {
*/
Long zCount(byte[] key, double min, double max);
/**
* Count number of elements within sorted set with scores between {@code Range#min} and {@code Range#max}.
*
* @param key
* @param min
* @param max
* @return
* @since 1.6
*/
Long zCount(byte[] key, Range range);
/**
* Get the size of sorted set with {@code key}.
* <p>
@@ -487,6 +566,16 @@ public interface RedisZSetCommands {
*/
Long zRemRangeByScore(byte[] key, double min, double max);
/**
* Remove elements with scores between {@code Range#min} and {@code Range#max} from sorted set with {@code key}.
*
* @param key
* @param range
* @return
* @since 1.6
*/
Long zRemRangeByScore(byte[] key, Range range);
/**
* Union sorted {@code sets} and store result in destination {@code key}.
* <p>
@@ -558,6 +647,16 @@ public interface RedisZSetCommands {
*/
Set<byte[]> zRangeByScore(byte[] key, String min, String max);
/**
* Get elements where score is between {@code Range#min} and {@code Range#max} from sorted set.
*
* @param key
* @param range
* @return
* @since 1.6
*/
Set<byte[]> zRangeByScore(byte[] key, Range range);
/**
* Get elements in range from {@code begin} to {@code end} where score is between {@code min} and {@code max} from
* sorted set.
@@ -574,6 +673,18 @@ public interface RedisZSetCommands {
*/
Set<byte[]> zRangeByScore(byte[] key, String min, String max, long offset, long count);
/**
* Get elements in range from {@code Limit#count} to {@code Limit#offset} where score is between {@code Range#min} and
* {@code Range#max} from sorted set.
*
* @param key
* @param range
* @param limit
* @return
* @since 1.6
*/
Set<byte[]> zRangeByScore(byte[] key, Range range, Limit limit);
/**
* Get all the elements in the sorted set at {@literal key} in lexicographical ordering.
*

View File

@@ -2058,6 +2058,24 @@ public class JedisConnection extends AbstractRedisConnection {
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zCount(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range)
*/
@Override
public Long zCount(byte[] key, Range range) {
if (isPipelined() || isQueueing()) {
throw new UnsupportedOperationException(
"ZCOUNT not implemented in jedis for binary protocol on transaction and pipeline");
}
byte[] min = JedisConverters.boundaryToBytesForZRange(range.getMin(), JedisConverters.NEGATIVE_INFINITY_BYTES);
byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES);
return jedis.zcount(key, min, max);
}
public Double zIncrBy(byte[] key, double increment, byte[] value) {
try {
if (isPipelined()) {
@@ -2164,8 +2182,8 @@ public class JedisConnection extends AbstractRedisConnection {
Assert.notNull(range, "Range cannot be null for ZRANGEBYLEX.");
byte[] min = JedisConverters.boundaryToBytesForZRangeByLex(range.getMin(), JedisConverters.toBytes("-"));
byte[] max = JedisConverters.boundaryToBytesForZRangeByLex(range.getMax(), JedisConverters.toBytes("+"));
byte[] min = JedisConverters.boundaryToBytesForZRangeByLex(range.getMin(), JedisConverters.MINUS_BYTES);
byte[] max = JedisConverters.boundaryToBytesForZRangeByLex(range.getMax(), JedisConverters.PLUS_BYTES);
try {
if (isPipelined()) {
@@ -2195,33 +2213,120 @@ public class JedisConnection extends AbstractRedisConnection {
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByScore(byte[], double, double)
*/
public Set<byte[]> zRangeByScore(byte[] key, double min, double max) {
return zRangeByScore(key, new Range().gte(min).lte(max));
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByScore(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range)
*/
@Override
public Set<byte[]> zRangeByScore(byte[] key, Range range) {
return zRangeByScore(key, range, null);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByScore(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range, org.springframework.data.redis.connection.RedisZSetCommands.Limit)
*/
@Override
public Set<byte[]> zRangeByScore(byte[] key, Range range, Limit limit) {
Assert.notNull(range, "Range cannot be null for ZRANGEBYSCORE.");
byte[] min = JedisConverters.boundaryToBytesForZRange(range.getMin(), JedisConverters.NEGATIVE_INFINITY_BYTES);
byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES);
try {
if (isPipelined()) {
pipeline(new JedisResult(pipeline.zrangeByScore(key, min, max)));
if (limit != null) {
pipeline(new JedisResult(pipeline.zrangeByScore(key, min, max, limit.getOffset(), limit.getCount())));
} else {
pipeline(new JedisResult(pipeline.zrangeByScore(key, min, max)));
}
return null;
}
if (isQueueing()) {
transaction(new JedisResult(transaction.zrangeByScore(key, min, max)));
if (limit != null) {
transaction(new JedisResult(transaction.zrangeByScore(key, min, max, limit.getOffset(), limit.getCount())));
} else {
transaction(new JedisResult(transaction.zrangeByScore(key, min, max)));
}
return null;
}
if (limit != null) {
return jedis.zrangeByScore(key, min, max, limit.getOffset(), limit.getCount());
}
return jedis.zrangeByScore(key, min, max);
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByScoreWithScores(byte[], double, double)
*/
public Set<Tuple> zRangeByScoreWithScores(byte[] key, double min, double max) {
return zRangeByScoreWithScores(key, new Range().gte(min).lte(max));
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByScoreWithScores(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range)
*/
@Override
public Set<Tuple> zRangeByScoreWithScores(byte[] key, Range range) {
return zRangeByScoreWithScores(key, range, null);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByScoreWithScores(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range, org.springframework.data.redis.connection.RedisZSetCommands.Limit)
*/
@Override
public Set<Tuple> zRangeByScoreWithScores(byte[] key, Range range, Limit limit) {
Assert.notNull(range, "Range cannot be null for ZRANGEBYSCOREWITHSCORES.");
byte[] min = JedisConverters.boundaryToBytesForZRange(range.getMin(), JedisConverters.NEGATIVE_INFINITY_BYTES);
byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES);
try {
if (isPipelined()) {
pipeline(new JedisResult(pipeline.zrangeByScoreWithScores(key, min, max), JedisConverters.tupleSetToTupleSet()));
if (limit != null) {
pipeline(new JedisResult(
pipeline.zrangeByScoreWithScores(key, min, max, limit.getOffset(), limit.getCount()),
JedisConverters.tupleSetToTupleSet()));
} else {
pipeline(new JedisResult(pipeline.zrangeByScoreWithScores(key, min, max),
JedisConverters.tupleSetToTupleSet()));
}
return null;
}
if (isQueueing()) {
transaction(new JedisResult(transaction.zrangeByScoreWithScores(key, min, max),
JedisConverters.tupleSetToTupleSet()));
if (limit != null) {
transaction(new JedisResult(transaction.zrangeByScoreWithScores(key, min, max, limit.getOffset(),
limit.getCount()), JedisConverters.tupleSetToTupleSet()));
} else {
transaction(new JedisResult(transaction.zrangeByScoreWithScores(key, min, max),
JedisConverters.tupleSetToTupleSet()));
}
return null;
}
if (limit != null) {
return JedisConverters.toTupleSet(jedis.zrangeByScoreWithScores(key, min, max, limit.getOffset(),
limit.getCount()));
}
return JedisConverters.toTupleSet(jedis.zrangeByScoreWithScores(key, min, max));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
@@ -2243,110 +2348,173 @@ public class JedisConnection extends AbstractRedisConnection {
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByScore(byte[], double, double, long, long)
*/
@Override
public Set<byte[]> zRangeByScore(byte[] key, double min, double max, long offset, long count) {
try {
if (isPipelined()) {
pipeline(new JedisResult(pipeline.zrangeByScore(key, min, max, (int) offset, (int) count)));
return null;
}
if (isQueueing()) {
transaction(new JedisResult(transaction.zrangeByScore(key, min, max, (int) offset, (int) count)));
return null;
}
return jedis.zrangeByScore(key, min, max, (int) offset, (int) count);
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
return zRangeByScore(key, new Range().gte(min).lte(max),
new Limit().offset(Long.valueOf(offset).intValue()).count(Long.valueOf(count).intValue()));
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeByScoreWithScores(byte[], double, double, long, long)
*/
@Override
public Set<Tuple> zRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count) {
try {
if (isPipelined()) {
pipeline(new JedisResult(pipeline.zrangeByScoreWithScores(key, min, max, (int) offset, (int) count),
JedisConverters.tupleSetToTupleSet()));
return null;
}
if (isQueueing()) {
transaction(new JedisResult(transaction.zrangeByScoreWithScores(key, min, max, (int) offset, (int) count),
JedisConverters.tupleSetToTupleSet()));
return null;
}
return JedisConverters.toTupleSet(jedis.zrangeByScoreWithScores(key, min, max, (int) offset, (int) count));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
return zRangeByScoreWithScores(key, new Range().gte(min).lte(max),
new Limit().offset(Long.valueOf(offset).intValue()).count(Long.valueOf(count).intValue()));
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByScore(byte[], double, double, long, long)
*/
@Override
public Set<byte[]> zRevRangeByScore(byte[] key, double min, double max, long offset, long count) {
try {
if (isPipelined()) {
pipeline(new JedisResult(pipeline.zrevrangeByScore(key, max, min, (int) offset, (int) count)));
return null;
}
if (isQueueing()) {
transaction(new JedisResult(transaction.zrevrangeByScore(key, max, min, (int) offset, (int) count)));
return null;
}
return jedis.zrevrangeByScore(key, max, min, (int) offset, (int) count);
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
return zRevRangeByScore(key, new Range().gte(min).lte(max), new Limit().offset(Long.valueOf(offset).intValue())
.count(Long.valueOf(count).intValue()));
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByScore(byte[], double, double)
*/
@Override
public Set<byte[]> zRevRangeByScore(byte[] key, double min, double max) {
return zRevRangeByScore(key, new Range().gte(min).lte(max));
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByScore(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range)
*/
@Override
public Set<byte[]> zRevRangeByScore(byte[] key, Range range) {
return zRevRangeByScore(key, range, null);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByScore(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range, org.springframework.data.redis.connection.RedisZSetCommands.Limit)
*/
@Override
public Set<byte[]> zRevRangeByScore(byte[] key, Range range, Limit limit) {
Assert.notNull(range, "Range cannot be null for ZREVRANGEBYSCORE.");
byte[] min = JedisConverters.boundaryToBytesForZRange(range.getMin(), JedisConverters.NEGATIVE_INFINITY_BYTES);
byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES);
try {
if (isPipelined()) {
pipeline(new JedisResult(pipeline.zrevrangeByScore(key, max, min)));
if (limit != null) {
pipeline(new JedisResult(pipeline.zrevrangeByScore(key, max, min, limit.getOffset(), limit.getCount())));
} else {
pipeline(new JedisResult(pipeline.zrevrangeByScore(key, max, min)));
}
return null;
}
if (isQueueing()) {
transaction(new JedisResult(transaction.zrevrangeByScore(key, max, min)));
if (limit != null) {
transaction(new JedisResult(transaction.zrevrangeByScore(key, max, min, limit.getOffset(), limit.getCount())));
} else {
transaction(new JedisResult(transaction.zrevrangeByScore(key, max, min)));
}
return null;
}
if (limit != null) {
return jedis.zrevrangeByScore(key, max, min, limit.getOffset(), limit.getCount());
}
return jedis.zrevrangeByScore(key, max, min);
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByScoreWithScores(byte[], double, double, long, long)
*/
@Override
public Set<Tuple> zRevRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count) {
try {
if (isPipelined()) {
pipeline(new JedisResult(pipeline.zrevrangeByScoreWithScores(key, max, min, (int) offset, (int) count),
JedisConverters.tupleSetToTupleSet()));
return null;
}
if (isQueueing()) {
transaction(new JedisResult(transaction.zrevrangeByScoreWithScores(key, max, min, (int) offset, (int) count),
JedisConverters.tupleSetToTupleSet()));
return null;
}
return JedisConverters.toTupleSet(jedis.zrevrangeByScoreWithScores(key, max, min, (int) offset, (int) count));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
return zRevRangeByScoreWithScores(key, new Range().gte(min).lte(max),
new Limit().offset(Long.valueOf(offset).intValue()).count(Long.valueOf(count).intValue()));
}
public Set<Tuple> zRevRangeByScoreWithScores(byte[] key, double min, double max) {
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByScoreWithScores(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range)
*/
@Override
public Set<Tuple> zRevRangeByScoreWithScores(byte[] key, Range range) {
return zRevRangeByScoreWithScores(key, range, null);
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByScoreWithScores(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range, org.springframework.data.redis.connection.RedisZSetCommands.Limit)
*/
@Override
public Set<Tuple> zRevRangeByScoreWithScores(byte[] key, Range range, Limit limit) {
Assert.notNull(range, "Range cannot be null for ZREVRANGEBYSCOREWITHSCORES.");
byte[] min = JedisConverters.boundaryToBytesForZRange(range.getMin(), JedisConverters.NEGATIVE_INFINITY_BYTES);
byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES);
try {
if (isPipelined()) {
pipeline(new JedisResult(pipeline.zrevrangeByScoreWithScores(key, max, min),
JedisConverters.tupleSetToTupleSet()));
if (limit != null) {
pipeline(new JedisResult(pipeline.zrevrangeByScoreWithScores(key, max, min, limit.getOffset(),
limit.getCount()), JedisConverters.tupleSetToTupleSet()));
} else {
pipeline(new JedisResult(pipeline.zrevrangeByScoreWithScores(key, max, min),
JedisConverters.tupleSetToTupleSet()));
}
return null;
}
if (isQueueing()) {
transaction(new JedisResult(transaction.zrevrangeByScoreWithScores(key, max, min),
JedisConverters.tupleSetToTupleSet()));
if (limit != null) {
transaction(new JedisResult(transaction.zrevrangeByScoreWithScores(key, max, min, limit.getOffset(),
limit.getCount()), JedisConverters.tupleSetToTupleSet()));
} else {
transaction(new JedisResult(transaction.zrevrangeByScoreWithScores(key, max, min),
JedisConverters.tupleSetToTupleSet()));
}
return null;
}
if (limit != null) {
return JedisConverters.toTupleSet(jedis.zrevrangeByScoreWithScores(key, max, min, limit.getOffset(),
limit.getCount()));
}
return JedisConverters.toTupleSet(jedis.zrevrangeByScoreWithScores(key, max, min));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByScoreWithScores(byte[], double, double)
*/
public Set<Tuple> zRevRangeByScoreWithScores(byte[] key, double min, double max) {
return zRevRangeByScoreWithScores(key, new Range().gte(min).lte(max), null);
}
public Long zRank(byte[] key, byte[] value) {
try {
if (isPipelined()) {
@@ -2395,7 +2563,27 @@ public class JedisConnection extends AbstractRedisConnection {
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRemRangeByScore(byte[], double, double)
*/
@Override
public Long zRemRangeByScore(byte[] key, double min, double max) {
return zRemRangeByScore(key, new Range().gte(min).lte(max));
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRemRangeByScore(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range)
*/
@Override
public Long zRemRangeByScore(byte[] key, Range range) {
Assert.notNull(range, "Range cannot be null for ZREMRANGEBYSCORE.");
byte[] min = JedisConverters.boundaryToBytesForZRange(range.getMin(), JedisConverters.NEGATIVE_INFINITY_BYTES);
byte[] max = JedisConverters.boundaryToBytesForZRange(range.getMax(), JedisConverters.POSITIVE_INFINITY_BYTES);
try {
if (isPipelined()) {
pipeline(new JedisResult(pipeline.zremrangeByScore(key, min, max)));
@@ -3330,4 +3518,5 @@ public class JedisConnection extends AbstractRedisConnection {
throw convertJedisAccessException(ex);
}
}
}

View File

@@ -20,7 +20,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.springframework.core.convert.converter.Converter;
@@ -50,7 +49,7 @@ import redis.clients.jedis.SortingParams;
import redis.clients.util.SafeEncoder;
/**
* Jedis type converters
* Jedis type converters.
*
* @author Jennifer Hickey
* @author Christoph Strobl
@@ -67,10 +66,15 @@ abstract public class JedisConverters extends Converters {
private static final Converter<Exception, DataAccessException> EXCEPTION_CONVERTER = new JedisExceptionConverter();
private static final Converter<String[], List<RedisClientInfo>> STRING_TO_CLIENT_INFO_CONVERTER = new StringToRedisClientInfoConverter();
private static final Converter<redis.clients.jedis.Tuple, Tuple> TUPLE_CONVERTER;
private static final Converter<Properties, RedisServer> PROPERTIES_TO_SENTINEL;
private static final ListConverter<redis.clients.jedis.Tuple, Tuple> TUPLE_LIST_TO_TUPLE_LIST_CONVERTER;
public static final byte[] PLUS_BYTES;
public static final byte[] MINUS_BYTES;
public static final byte[] POSITIVE_INFINITY_BYTES;
public static final byte[] NEGATIVE_INFINITY_BYTES;
static {
STRING_TO_BYTES = new Converter<String, byte[]>() {
public byte[] convert(String source) {
return source == null ? null : SafeEncoder.encode(source);
@@ -87,14 +91,11 @@ abstract public class JedisConverters extends Converters {
};
TUPLE_SET_TO_TUPLE_SET = new SetConverter<redis.clients.jedis.Tuple, Tuple>(TUPLE_CONVERTER);
TUPLE_LIST_TO_TUPLE_LIST_CONVERTER = new ListConverter<redis.clients.jedis.Tuple, Tuple>(TUPLE_CONVERTER);
PROPERTIES_TO_SENTINEL = new Converter<Properties, RedisServer>() {
@Override
public RedisServer convert(Properties source) {
return source != null ? RedisServer.newServerFrom(source) : null;
}
};
PLUS_BYTES = toBytes("+");
MINUS_BYTES = toBytes("-");
POSITIVE_INFINITY_BYTES = toBytes("+inf");
NEGATIVE_INFINITY_BYTES = toBytes("-inf");
}
public static Converter<String, byte[]> stringToBytes() {
@@ -151,6 +152,15 @@ abstract public class JedisConverters extends Converters {
return String.valueOf(source).getBytes();
}
/**
* @param source
* @return
* @since 1.6
*/
public static byte[] toBytes(Double source) {
return toBytes(String.valueOf(source));
}
public static byte[] toBytes(String source) {
return STRING_TO_BYTES.convert(source);
}
@@ -252,6 +262,24 @@ abstract public class JedisConverters extends Converters {
}
}
/**
* Converts a given {@link Boundary} to its binary representation suitable for {@literal ZRANGEBY*} commands, despite
* {@literal ZRANGEBYLEX}.
*
* @param boundary
* @param defaultValue
* @return
* @since 1.6
*/
public static byte[] boundaryToBytesForZRange(Boundary boundary, byte[] defaultValue) {
if (boundary == null || boundary.getValue() == null) {
return defaultValue;
}
return boundaryToBytes(boundary, new byte[] {}, toBytes("("));
}
/**
* Converts a given {@link Boundary} to its binary representation suitable for ZRANGEBYLEX command.
*
@@ -265,10 +293,17 @@ abstract public class JedisConverters extends Converters {
return defaultValue;
}
byte[] prefix = boundary.isIncluding() ? toBytes("[") : toBytes("(");
return boundaryToBytes(boundary, toBytes("["), toBytes("("));
}
private static byte[] boundaryToBytes(Boundary boundary, byte[] inclPrefix, byte[] exclPrefix) {
byte[] prefix = boundary.isIncluding() ? inclPrefix : exclPrefix;
byte[] value = null;
if (boundary.getValue() instanceof byte[]) {
value = (byte[]) boundary.getValue();
} else if (boundary.getValue() instanceof Double) {
value = toBytes((Double) boundary.getValue());
} else if (boundary.getValue() instanceof Long) {
value = toBytes((Long) boundary.getValue());
} else if (boundary.getValue() instanceof Integer) {
@@ -283,5 +318,6 @@ abstract public class JedisConverters extends Converters {
buffer.put(prefix);
buffer.put(value);
return buffer.array();
}
}

View File

@@ -899,6 +899,17 @@ public class JredisConnection extends AbstractRedisConnection {
}
public Long zCount(byte[] key, double min, double max) {
return zCount(key, new Range().gte(min).lte(max));
}
@Override
public Long zCount(byte[] key, Range range) {
Assert.notNull(range, "Range for ZCOUNT must not be null!");
double min = ((Double) range.getMin().getValue()).doubleValue();
double max = ((Double) range.getMax().getValue()).doubleValue();
try {
return jredis.zcount(key, min, max);
} catch (Exception ex) {
@@ -946,6 +957,16 @@ public class JredisConnection extends AbstractRedisConnection {
throw new UnsupportedOperationException();
}
@Override
public Set<Tuple> zRangeByScoreWithScores(byte[] key, Range range) {
throw new UnsupportedOperationException();
}
@Override
public Set<Tuple> zRangeByScoreWithScores(byte[] key, Range range, Limit limit) {
throw new UnsupportedOperationException();
}
public Set<byte[]> zRangeByScore(byte[] key, double min, double max, long offset, long count) {
throw new UnsupportedOperationException();
}
@@ -1346,4 +1367,39 @@ public class JredisConnection extends AbstractRedisConnection {
public Set<byte[]> zRangeByLex(byte[] key, Range range, Limit limit) {
throw new UnsupportedOperationException("ZRANGEBYLEX is no supported for jredis.");
}
@Override
public Set<byte[]> zRevRangeByScore(byte[] key, Range range) {
throw new UnsupportedOperationException();
}
@Override
public Set<byte[]> zRevRangeByScore(byte[] key, Range range, Limit limit) {
throw new UnsupportedOperationException();
}
@Override
public Set<Tuple> zRevRangeByScoreWithScores(byte[] key, Range range, Limit limit) {
throw new UnsupportedOperationException();
}
@Override
public Long zRemRangeByScore(byte[] key, Range range) {
throw new UnsupportedOperationException();
}
@Override
public Set<byte[]> zRangeByScore(byte[] key, Range range) {
throw new UnsupportedOperationException();
}
@Override
public Set<byte[]> zRangeByScore(byte[] key, Range range, Limit limit) {
throw new UnsupportedOperationException();
}
@Override
public Set<Tuple> zRevRangeByScoreWithScores(byte[] key, Range range) {
throw new UnsupportedOperationException();
}
}

View File

@@ -2109,7 +2109,19 @@ public class LettuceConnection extends AbstractRedisConnection {
}
}
@Override
public Long zCount(byte[] key, double min, double max) {
return zCount(key, new Range().gte(min).lte(max));
}
@Override
public Long zCount(byte[] key, Range range) {
Assert.notNull(range, "Range for ZCOUNT must not be null!");
String min = LettuceConverters.boundaryToStringForZRange(range.getMin(), "-inf");
String max = LettuceConverters.boundaryToStringForZRange(range.getMax(), "+inf");
try {
if (isPipelined()) {
pipeline(new LettuceResult(getAsyncConnection().zcount(key, min, max)));
@@ -2211,36 +2223,98 @@ public class LettuceConnection extends AbstractRedisConnection {
}
}
@Override
public Set<byte[]> zRangeByScore(byte[] key, double min, double max) {
return zRangeByScore(key, new Range().gte(min).lte(max));
}
@Override
public Set<byte[]> zRangeByScore(byte[] key, Range range) {
return zRangeByScore(key, range, null);
}
@Override
public Set<byte[]> zRangeByScore(byte[] key, Range range, Limit limit) {
Assert.notNull(range, "Range for ZRANGEBYSCORE must not be null!");
String min = LettuceConverters.boundaryToStringForZRange(range.getMin(), "-inf");
String max = LettuceConverters.boundaryToStringForZRange(range.getMax(), "+inf");
try {
if (isPipelined()) {
pipeline(new LettuceResult(getAsyncConnection().zrangebyscore(key, min, max),
LettuceConverters.bytesListToBytesSet()));
if (limit != null) {
pipeline(new LettuceResult(getAsyncConnection().zrangebyscore(key, min, max, limit.getOffset(),
limit.getCount()), LettuceConverters.bytesListToBytesSet()));
} else {
pipeline(new LettuceResult(getAsyncConnection().zrangebyscore(key, min, max),
LettuceConverters.bytesListToBytesSet()));
}
return null;
}
if (isQueueing()) {
transaction(new LettuceTxResult(getConnection().zrangebyscore(key, min, max),
LettuceConverters.bytesListToBytesSet()));
if (limit != null) {
transaction(new LettuceTxResult(getConnection().zrangebyscore(key, min, max, limit.getOffset(),
limit.getCount()), LettuceConverters.bytesListToBytesSet()));
} else {
transaction(new LettuceTxResult(getConnection().zrangebyscore(key, min, max),
LettuceConverters.bytesListToBytesSet()));
}
return null;
}
if (limit != null) {
return LettuceConverters.toBytesSet(getConnection().zrangebyscore(key, min, max, limit.getOffset(),
limit.getCount()));
}
return LettuceConverters.toBytesSet(getConnection().zrangebyscore(key, min, max));
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
@Override
public Set<Tuple> zRangeByScoreWithScores(byte[] key, double min, double max) {
return zRangeByScoreWithScores(key, new Range().gte(min).lte(max));
}
@Override
public Set<Tuple> zRangeByScoreWithScores(byte[] key, Range range) {
return zRangeByScoreWithScores(key, range, null);
}
@Override
public Set<Tuple> zRangeByScoreWithScores(byte[] key, Range range, Limit limit) {
Assert.notNull(range, "Range for ZRANGEBYSCOREWITHSCORES must not be null!");
String min = LettuceConverters.boundaryToStringForZRange(range.getMin(), "-inf");
String max = LettuceConverters.boundaryToStringForZRange(range.getMax(), "+inf");
try {
if (isPipelined()) {
pipeline(new LettuceResult(getAsyncConnection().zrangebyscoreWithScores(key, min, max),
LettuceConverters.scoredValuesToTupleSet()));
if (limit != null) {
pipeline(new LettuceResult(getAsyncConnection().zrangebyscoreWithScores(key, min, max, limit.getOffset(),
limit.getCount()), LettuceConverters.scoredValuesToTupleSet()));
} else {
pipeline(new LettuceResult(getAsyncConnection().zrangebyscoreWithScores(key, min, max),
LettuceConverters.scoredValuesToTupleSet()));
}
return null;
}
if (isQueueing()) {
transaction(new LettuceTxResult(getConnection().zrangebyscoreWithScores(key, min, max),
LettuceConverters.scoredValuesToTupleSet()));
if (limit != null) {
transaction(new LettuceTxResult(getConnection().zrangebyscoreWithScores(key, min, max, limit.getOffset(),
limit.getCount()), LettuceConverters.scoredValuesToTupleSet()));
} else {
transaction(new LettuceTxResult(getConnection().zrangebyscoreWithScores(key, min, max),
LettuceConverters.scoredValuesToTupleSet()));
}
return null;
}
if (limit != null) {
return LettuceConverters.toTupleSet(getConnection().zrangebyscoreWithScores(key, min, max, limit.getOffset(),
limit.getCount()));
}
return LettuceConverters.toTupleSet(getConnection().zrangebyscoreWithScores(key, min, max));
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
@@ -2265,114 +2339,132 @@ public class LettuceConnection extends AbstractRedisConnection {
}
}
@Override
public Set<byte[]> zRangeByScore(byte[] key, double min, double max, long offset, long count) {
try {
if (isPipelined()) {
pipeline(new LettuceResult(getAsyncConnection().zrangebyscore(key, min, max, offset, count),
LettuceConverters.bytesListToBytesSet()));
return null;
}
if (isQueueing()) {
transaction(new LettuceTxResult(getConnection().zrangebyscore(key, min, max, offset, count),
LettuceConverters.bytesListToBytesSet()));
return null;
}
return LettuceConverters.toBytesSet(getConnection().zrangebyscore(key, min, max, offset, count));
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
return zRangeByScore(key, new Range().gte(min).lte(max),
new Limit().offset(Long.valueOf(offset).intValue()).count(Long.valueOf(count).intValue()));
}
@Override
public Set<Tuple> zRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count) {
try {
if (isPipelined()) {
pipeline(new LettuceResult(getAsyncConnection().zrangebyscoreWithScores(key, min, max, offset, count),
LettuceConverters.scoredValuesToTupleSet()));
return null;
}
if (isQueueing()) {
transaction(new LettuceTxResult(getConnection().zrangebyscoreWithScores(key, min, max, offset, count),
LettuceConverters.scoredValuesToTupleSet()));
return null;
}
return LettuceConverters.toTupleSet(getConnection().zrangebyscoreWithScores(key, min, max, offset, count));
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
return zRangeByScoreWithScores(key, new Range().gte(min).lte(max),
new Limit().offset(Long.valueOf(offset).intValue()).count(Long.valueOf(count).intValue()));
}
@Override
public Set<byte[]> zRevRangeByScore(byte[] key, double min, double max, long offset, long count) {
try {
if (isPipelined()) {
pipeline(new LettuceResult(getAsyncConnection().zrevrangebyscore(key, max, min, offset, count),
LettuceConverters.bytesListToBytesSet()));
return null;
}
if (isQueueing()) {
transaction(new LettuceTxResult(getConnection().zrevrangebyscore(key, max, min, offset, count),
LettuceConverters.bytesListToBytesSet()));
return null;
}
return LettuceConverters.toBytesSet(getConnection().zrevrangebyscore(key, max, min, offset, count));
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
return zRevRangeByScore(key, new Range().gte(min).lte(max), new Limit().offset(Long.valueOf(offset).intValue())
.count(Long.valueOf(count).intValue()));
}
public Set<byte[]> zRevRangeByScore(byte[] key, double min, double max) {
@Override
public Set<byte[]> zRevRangeByScore(byte[] key, Range range) {
return zRevRangeByScore(key, range, null);
}
@Override
public Set<byte[]> zRevRangeByScore(byte[] key, Range range, Limit limit) {
Assert.notNull(range, "Range for ZREVRANGEBYSCORE must not be null!");
String min = LettuceConverters.boundaryToStringForZRange(range.getMin(), "-inf");
String max = LettuceConverters.boundaryToStringForZRange(range.getMax(), "+inf");
try {
if (isPipelined()) {
pipeline(new LettuceResult(getAsyncConnection().zrevrangebyscore(key, max, min),
LettuceConverters.bytesListToBytesSet()));
if (limit != null) {
pipeline(new LettuceResult(getAsyncConnection().zrevrangebyscore(key, max, min, limit.getOffset(),
limit.getCount()), LettuceConverters.bytesListToBytesSet()));
} else {
pipeline(new LettuceResult(getAsyncConnection().zrevrangebyscore(key, max, min),
LettuceConverters.bytesListToBytesSet()));
}
return null;
}
if (isQueueing()) {
transaction(new LettuceTxResult(getConnection().zrevrangebyscore(key, max, min),
LettuceConverters.bytesListToBytesSet()));
if (limit != null) {
transaction(new LettuceTxResult(getConnection().zrevrangebyscore(key, max, min, limit.getOffset(),
limit.getCount()), LettuceConverters.bytesListToBytesSet()));
} else {
transaction(new LettuceTxResult(getConnection().zrevrangebyscore(key, max, min),
LettuceConverters.bytesListToBytesSet()));
}
return null;
}
if (limit != null) {
return LettuceConverters.toBytesSet(getConnection().zrevrangebyscore(key, max, min, limit.getOffset(),
limit.getCount()));
}
return LettuceConverters.toBytesSet(getConnection().zrevrangebyscore(key, max, min));
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
public Set<Tuple> zRevRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count) {
try {
if (isPipelined()) {
pipeline(new LettuceResult(getAsyncConnection().zrevrangebyscoreWithScores(key, max, min, offset, count),
LettuceConverters.scoredValuesToTupleSet()));
return null;
}
if (isQueueing()) {
transaction(new LettuceTxResult(getConnection().zrevrangebyscoreWithScores(key, max, min, offset, count),
LettuceConverters.scoredValuesToTupleSet()));
return null;
}
return LettuceConverters.toTupleSet(getConnection().zrevrangebyscoreWithScores(key, max, min, offset, count));
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
@Override
public Set<byte[]> zRevRangeByScore(byte[] key, double min, double max) {
return zRevRangeByScore(key, new Range().gte(min).lte(max));
}
public Set<Tuple> zRevRangeByScoreWithScores(byte[] key, double min, double max) {
@Override
public Set<Tuple> zRevRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count) {
return zRevRangeByScoreWithScores(key, new Range().gte(min).lte(max),
new Limit().offset(Long.valueOf(offset).intValue()).count(Long.valueOf(count).intValue()));
}
@Override
public Set<Tuple> zRevRangeByScoreWithScores(byte[] key, Range range) {
return zRevRangeByScoreWithScores(key, range, null);
}
@Override
public Set<Tuple> zRevRangeByScoreWithScores(byte[] key, Range range, Limit limit) {
Assert.notNull(range, "Range for ZREVRANGEBYSCOREWITHSCORES must not be null!");
String min = LettuceConverters.boundaryToStringForZRange(range.getMin(), "-inf");
String max = LettuceConverters.boundaryToStringForZRange(range.getMax(), "+inf");
try {
if (isPipelined()) {
pipeline(new LettuceResult(getAsyncConnection().zrevrangebyscoreWithScores(key, max, min),
LettuceConverters.scoredValuesToTupleSet()));
if (limit != null) {
pipeline(new LettuceResult(getAsyncConnection().zrevrangebyscoreWithScores(key, max, min, limit.getOffset(),
limit.getCount()), LettuceConverters.scoredValuesToTupleSet()));
} else {
pipeline(new LettuceResult(getAsyncConnection().zrevrangebyscoreWithScores(key, max, min),
LettuceConverters.scoredValuesToTupleSet()));
}
return null;
}
if (isQueueing()) {
transaction(new LettuceTxResult(getConnection().zrevrangebyscoreWithScores(key, max, min),
LettuceConverters.scoredValuesToTupleSet()));
if (limit != null) {
transaction(new LettuceTxResult(getConnection().zrevrangebyscoreWithScores(key, max, min, limit.getOffset(),
limit.getCount()), LettuceConverters.scoredValuesToTupleSet()));
} else {
transaction(new LettuceTxResult(getConnection().zrevrangebyscoreWithScores(key, max, min),
LettuceConverters.scoredValuesToTupleSet()));
}
return null;
}
if (limit != null) {
return LettuceConverters.toTupleSet(getConnection().zrevrangebyscoreWithScores(key, max, min,
limit.getOffset(), limit.getCount()));
}
return LettuceConverters.toTupleSet(getConnection().zrevrangebyscoreWithScores(key, max, min));
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
@Override
public Set<Tuple> zRevRangeByScoreWithScores(byte[] key, double min, double max) {
return zRevRangeByScoreWithScores(key, new Range().gte(min).lte(max));
}
public Long zRank(byte[] key, byte[] value) {
try {
if (isPipelined()) {
@@ -2421,7 +2513,19 @@ public class LettuceConnection extends AbstractRedisConnection {
}
}
@Override
public Long zRemRangeByScore(byte[] key, double min, double max) {
return zRemRangeByScore(key, new Range().gte(min).lte(max));
}
@Override
public Long zRemRangeByScore(byte[] key, Range range) {
Assert.notNull(range, "Range for ZREMRANGEBYSCORE must not be null!");
String min = LettuceConverters.boundaryToStringForZRange(range.getMin(), "-inf");
String max = LettuceConverters.boundaryToStringForZRange(range.getMax(), "+inf");
try {
if (isPipelined()) {
pipeline(new LettuceResult(getAsyncConnection().zremrangebyscore(key, min, max)));

View File

@@ -30,6 +30,7 @@ import org.springframework.core.convert.converter.Converter;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.DefaultTuple;
import org.springframework.data.redis.connection.RedisListCommands.Position;
import org.springframework.data.redis.connection.RedisZSetCommands.Range.Boundary;
import org.springframework.data.redis.connection.RedisZSetCommands.Tuple;
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.connection.SortParameters;
@@ -329,4 +330,26 @@ abstract public class LettuceConverters extends Converters {
return stringToRedisClientListConverter().convert(clientList);
}
public static String boundaryToStringForZRange(Boundary boundary, String defaultValue) {
if (boundary == null || boundary.getValue() == null) {
return defaultValue;
}
return boundaryToString(boundary, "", "(");
}
private static String boundaryToString(Boundary boundary, String inclPrefix, String exclPrefix) {
String prefix = boundary.isIncluding() ? inclPrefix : exclPrefix;
String value = null;
if (boundary.getValue() instanceof byte[]) {
value = toString((byte[]) boundary.getValue());
} else {
value = boundary.getValue().toString();
}
return prefix + value;
}
}

View File

@@ -1574,6 +1574,15 @@ public class SrpConnection extends AbstractRedisConnection {
}
public Long zCount(byte[] key, double min, double max) {
return zCount(key, new Range().gte(min).lte(max));
}
@Override
public Long zCount(byte[] key, Range range) {
byte[] min = SrpConverters.boundaryToBytesForZRange(range.getMin(), SrpConverters.toBytes("-inf"));
byte[] max = SrpConverters.boundaryToBytesForZRange(range.getMax(), SrpConverters.toBytes("+inf"));
try {
if (isPipelined()) {
pipeline(new SrpResult(pipeline.zcount(key, min, max)));
@@ -1638,26 +1647,61 @@ public class SrpConnection extends AbstractRedisConnection {
}
public Set<byte[]> zRangeByScore(byte[] key, double min, double max) {
return zRangeByScore(key, new Range().gte(min).lte(max));
}
@Override
public Set<byte[]> zRangeByScore(byte[] key, Range range) {
return zRangeByScore(key, range, null);
}
@Override
public Set<byte[]> zRangeByScore(byte[] key, Range range, Limit limit) {
Assert.notNull(range, "Range for ZRANGEBYSCORE must not be null!");
byte[] min = SrpConverters.boundaryToBytesForZRange(range.getMin(), SrpConverters.toBytes("-inf"));
byte[] max = SrpConverters.boundaryToBytesForZRange(range.getMax(), SrpConverters.toBytes("+inf"));
Object[] params = limit != null ? limitParams(limit.getOffset(), limit.getCount()) : EMPTY_PARAMS_ARRAY;
try {
if (isPipelined()) {
pipeline(new SrpResult(pipeline.zrangebyscore(key, min, max, null, EMPTY_PARAMS_ARRAY),
SrpConverters.repliesToBytesSet()));
pipeline(new SrpResult(pipeline.zrangebyscore(key, min, max, null, params), SrpConverters.repliesToBytesSet()));
return null;
}
return SrpConverters.toBytesSet(client.zrangebyscore(key, min, max, null, EMPTY_PARAMS_ARRAY).data());
return SrpConverters.toBytesSet(client.zrangebyscore(key, min, max, null, params).data());
} catch (Exception ex) {
throw convertSrpAccessException(ex);
}
}
public Set<Tuple> zRangeByScoreWithScores(byte[] key, double min, double max) {
return zRangeByScoreWithScores(key, new Range().gte(min).lte(max));
}
@Override
public Set<Tuple> zRangeByScoreWithScores(byte[] key, Range range) {
return zRangeByScoreWithScores(key, range, null);
}
@Override
public Set<Tuple> zRangeByScoreWithScores(byte[] key, Range range, Limit limit) {
Assert.notNull(range, "Range for ZRANGEBYSCOREWITHSCORES must not be null!");
byte[] min = SrpConverters.boundaryToBytesForZRange(range.getMin(), SrpConverters.toBytes("-inf"));
byte[] max = SrpConverters.boundaryToBytesForZRange(range.getMax(), SrpConverters.toBytes("+inf"));
Object[] params = limit != null ? limitParams(limit.getOffset(), limit.getCount()) : EMPTY_PARAMS_ARRAY;
try {
if (isPipelined()) {
pipeline(new SrpResult(pipeline.zrangebyscore(key, min, max, WITHSCORES, EMPTY_PARAMS_ARRAY),
pipeline(new SrpResult(pipeline.zrangebyscore(key, min, max, WITHSCORES, params),
SrpConverters.repliesToTupleSet()));
return null;
}
return SrpConverters.toTupleSet(client.zrangebyscore(key, min, max, WITHSCORES, EMPTY_PARAMS_ARRAY).data());
return SrpConverters.toTupleSet(client.zrangebyscore(key, min, max, WITHSCORES, params).data());
} catch (Exception ex) {
throw convertSrpAccessException(ex);
}
@@ -1675,81 +1719,91 @@ public class SrpConnection extends AbstractRedisConnection {
}
}
@Override
public Set<byte[]> zRangeByScore(byte[] key, double min, double max, long offset, long count) {
try {
Object[] limit = limitParams(offset, count);
if (isPipelined()) {
pipeline(new SrpResult(pipeline.zrangebyscore(key, min, max, null, limit), SrpConverters.repliesToBytesSet()));
return null;
}
return SrpConverters.toBytesSet(client.zrangebyscore(key, min, max, null, limit).data());
} catch (Exception ex) {
throw convertSrpAccessException(ex);
}
return zRangeByScore(key, new Range().gte(min).lte(max),
new Limit().offset(Long.valueOf(offset).intValue()).count(Long.valueOf(count).intValue()));
}
@Override
public Set<Tuple> zRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count) {
try {
Object[] limit = limitParams(offset, count);
if (isPipelined()) {
pipeline(new SrpResult(pipeline.zrangebyscore(key, min, max, WITHSCORES, limit),
SrpConverters.repliesToTupleSet()));
return null;
}
return SrpConverters.toTupleSet(client.zrangebyscore(key, min, max, WITHSCORES, limit).data());
} catch (Exception ex) {
throw convertSrpAccessException(ex);
}
return zRangeByScoreWithScores(key, new Range().gte(min).lte(max),
new Limit().offset(Long.valueOf(offset).intValue()).count(Long.valueOf(count).intValue()));
}
public Set<byte[]> zRevRangeByScore(byte[] key, double min, double max, long offset, long count) {
try {
Object[] limit = limitParams(offset, count);
if (isPipelined()) {
pipeline(new SrpResult(pipeline.zrevrangebyscore(key, max, min, null, limit), SrpConverters.repliesToBytesSet()));
return null;
}
return SrpConverters.toBytesSet(client.zrevrangebyscore(key, max, min, null, limit).data());
} catch (Exception ex) {
throw convertSrpAccessException(ex);
}
return zRevRangeByScore(key, new Range().gte(min).lte(max), new Limit().offset(Long.valueOf(offset).intValue())
.count(Long.valueOf(count).intValue()));
}
@Override
public Set<byte[]> zRevRangeByScore(byte[] key, double min, double max) {
return zRevRangeByScore(key, new Range().gte(min).lte(max));
}
@Override
public Set<Tuple> zRevRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count) {
return zRevRangeByScoreWithScores(key, new Range().gte(min).lte(max),
new Limit().offset(Long.valueOf(offset).intValue()).count(Long.valueOf(count).intValue()));
}
@Override
public Set<Tuple> zRevRangeByScoreWithScores(byte[] key, double min, double max) {
return zRevRangeByScoreWithScores(key, new Range().gte(min).lte(max));
}
@Override
public Set<byte[]> zRevRangeByScore(byte[] key, Range range) {
return zRevRangeByScore(key, range, null);
}
@Override
public Set<byte[]> zRevRangeByScore(byte[] key, Range range, Limit limit) {
Assert.notNull(range, "Range for ZRANGEBYSCOREWITHSCORES must not be null!");
byte[] min = SrpConverters.boundaryToBytesForZRange(range.getMin(), SrpConverters.toBytes("-inf"));
byte[] max = SrpConverters.boundaryToBytesForZRange(range.getMax(), SrpConverters.toBytes("+inf"));
Object[] params = limit != null ? limitParams(limit.getOffset(), limit.getCount()) : EMPTY_PARAMS_ARRAY;
try {
if (isPipelined()) {
pipeline(new SrpResult(pipeline.zrevrangebyscore(key, max, min, null, EMPTY_PARAMS_ARRAY),
pipeline(new SrpResult(pipeline.zrevrangebyscore(key, max, min, null, params),
SrpConverters.repliesToBytesSet()));
return null;
}
return SrpConverters.toBytesSet(client.zrevrangebyscore(key, max, min, null, EMPTY_PARAMS_ARRAY).data());
return SrpConverters.toBytesSet(client.zrevrangebyscore(key, max, min, null, params).data());
} catch (Exception ex) {
throw convertSrpAccessException(ex);
}
}
public Set<Tuple> zRevRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count) {
try {
Object[] limit = limitParams(offset, count);
if (isPipelined()) {
pipeline(new SrpResult(pipeline.zrevrangebyscore(key, max, min, WITHSCORES, limit),
SrpConverters.repliesToTupleSet()));
return null;
}
return SrpConverters.toTupleSet(client.zrevrangebyscore(key, max, min, WITHSCORES, limit).data());
} catch (Exception ex) {
throw convertSrpAccessException(ex);
}
@Override
public Set<Tuple> zRevRangeByScoreWithScores(byte[] key, Range range) {
return zRevRangeByScoreWithScores(key, range, null);
}
public Set<Tuple> zRevRangeByScoreWithScores(byte[] key, double min, double max) {
@Override
public Set<Tuple> zRevRangeByScoreWithScores(byte[] key, Range range, Limit limit) {
Assert.notNull(range, "Range for ZRANGEBYSCOREWITHSCORES must not be null!");
byte[] min = SrpConverters.boundaryToBytesForZRange(range.getMin(), SrpConverters.toBytes("-inf"));
byte[] max = SrpConverters.boundaryToBytesForZRange(range.getMax(), SrpConverters.toBytes("+inf"));
Object[] params = limit != null ? limitParams(limit.getOffset(), limit.getCount()) : EMPTY_PARAMS_ARRAY;
try {
if (isPipelined()) {
pipeline(new SrpResult(pipeline.zrevrangebyscore(key, max, min, WITHSCORES, EMPTY_PARAMS_ARRAY),
pipeline(new SrpResult(pipeline.zrevrangebyscore(key, max, min, WITHSCORES, params),
SrpConverters.repliesToTupleSet()));
return null;
}
return SrpConverters.toTupleSet(client.zrevrangebyscore(key, max, min, WITHSCORES, EMPTY_PARAMS_ARRAY).data());
return SrpConverters.toTupleSet(client.zrevrangebyscore(key, max, min, WITHSCORES, params).data());
} catch (Exception ex) {
throw convertSrpAccessException(ex);
}
@@ -1792,6 +1846,15 @@ public class SrpConnection extends AbstractRedisConnection {
}
public Long zRemRangeByScore(byte[] key, double min, double max) {
return zRemRangeByScore(key, new Range().gte(min).lte(max));
}
@Override
public Long zRemRangeByScore(byte[] key, Range range) {
byte[] min = SrpConverters.boundaryToBytesForZRange(range.getMin(), SrpConverters.toBytes("-inf"));
byte[] max = SrpConverters.boundaryToBytesForZRange(range.getMax(), SrpConverters.toBytes("+inf"));
try {
if (isPipelined()) {
pipeline(new SrpResult(pipeline.zremrangebyscore(key, min, max)));
@@ -2557,4 +2620,5 @@ public class SrpConnection extends AbstractRedisConnection {
public Set<byte[]> zRangeByLex(byte[] key, Range range, Limit limit) {
throw new UnsupportedOperationException("ZRANGEBYLEX is no supported for srp.");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2014 the original author or authors.
* Copyright 2013-2015 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.
@@ -16,6 +16,7 @@
package org.springframework.data.redis.connection.srp;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
@@ -32,6 +33,7 @@ import org.springframework.data.redis.RedisSystemException;
import org.springframework.data.redis.connection.DefaultTuple;
import org.springframework.data.redis.connection.RedisListCommands.Position;
import org.springframework.data.redis.connection.RedisStringCommands.BitOperation;
import org.springframework.data.redis.connection.RedisZSetCommands.Range.Boundary;
import org.springframework.data.redis.connection.RedisZSetCommands.Tuple;
import org.springframework.data.redis.connection.convert.Converters;
import org.springframework.data.redis.connection.convert.LongToBooleanConverter;
@@ -413,4 +415,42 @@ abstract public class SrpConverters extends Converters {
public static Converter<Exception, DataAccessException> exceptionConverter() {
return EXCEPTION_CONVERTER;
}
/**
* Converts a given {@link Boundary} to its binary representation suitable for {@literal ZRANGEBY*} commands, despite
* {@literal ZRANGEBYLEX}.
*
* @param boundary
* @param defaultValue
* @return
* @since 1.6
*/
public static byte[] boundaryToBytesForZRange(Boundary boundary, byte[] defaultValue) {
if (boundary == null || boundary.getValue() == null) {
return defaultValue;
}
return boundaryToBytes(boundary, new byte[] {}, "(".getBytes(Charsets.UTF_8));
}
public static byte[] toBytes(String source) {
return source.getBytes(Charsets.UTF_8);
}
private static byte[] boundaryToBytes(Boundary boundary, byte[] inclPrefix, byte[] exclPrefix) {
byte[] prefix = boundary.isIncluding() ? inclPrefix : exclPrefix;
byte[] value = null;
if (boundary.getValue() instanceof byte[]) {
value = (byte[]) boundary.getValue();
} else {
value = toBytes(boundary.getValue().toString());
}
ByteBuffer buffer = ByteBuffer.allocate(prefix.length + value.length);
buffer.put(prefix);
buffer.put(value);
return buffer.array();
}
}