DATAREDIS-106 - Support for open interval for scores for sorted sets.

We now support open zset's interval for JedisConnection, JredisConnection, LettuceConnection, SrpConnection and DefaultStringRedisConnection.

Original pull request: #97.
This commit is contained in:
Thomas Darimont
2014-10-27 11:18:09 +01:00
committed by Christoph Strobl
parent 5ca672d180
commit cf46d6e766
12 changed files with 300 additions and 1 deletions

View File

@@ -2393,4 +2393,44 @@ public class DefaultStringRedisConnection implements StringRedisConnection {
return delegate.getSentinelConnection();
}
@Override
public Set<byte[]> zRangeByScore(String key, String min, String max) {
Set<byte[]> results = delegate.zRangeByScore(serialize(key), min, max);
if (isFutureConversion()) {
addResultConverter(identityConverter);
}
return results;
}
@Override
public Set<byte[]> zRangeByScore(String key, String min, String max, long offset, long count) {
Set<byte[]> results = delegate.zRangeByScore(serialize(key), min, max, offset, count);
if (isFutureConversion()) {
addResultConverter(identityConverter);
}
return results;
}
@Override
public Set<byte[]> zRangeByScore(byte[] key, String min, String max) {
Set<byte[]> results = delegate.zRangeByScore(key, min, max);
if (isFutureConversion()) {
addResultConverter(identityConverter);
}
return results;
}
@Override
public Set<byte[]> zRangeByScore(byte[] key, String min, String max, long offset, long count) {
Set<byte[]> results = delegate.zRangeByScore(key, min, max, offset, count);
if (isFutureConversion()) {
addResultConverter(identityConverter);
}
return results;
}
}

View File

@@ -25,6 +25,8 @@ import org.springframework.data.redis.core.ScanOptions;
*
* @author Costin Leau
* @author Christoph Strobl
* @author Thomas Darimont
* @author David Liu
*/
public interface RedisZSetCommands {
@@ -346,4 +348,29 @@ public interface RedisZSetCommands {
* @return
*/
Cursor<Tuple> zScan(byte[] key, ScanOptions options);
/**
* Get elements where score is between {@code min} and {@code max} from sorted set.
*
* @since 1.5
* @see http://redis.io/commands/zrangebyscore
* @param key
* @param begin
* @param end
* @return
*/
Set<byte[]> zRangeByScore(byte[] key, String min, String max);
/**
* Get elements in range from {@code begin} to {@code end} where score is between {@code min} and {@code max} from
* sorted set.
*
* @since 1.5
* @see http://redis.io/commands/zrangebyscore
* @param key
* @param begin
* @param end
* @return
*/
Set<byte[]> zRangeByScore(byte[] key, String min, String max, long offset, long count);
}

View File

@@ -33,6 +33,9 @@ import org.springframework.data.redis.serializer.RedisSerializer;
*
* @author Costin Leau
* @author Christoph Strobl
* @author Thomas Darimont
* @author David Liu
*
* @see RedisCallback
* @see RedisSerializer
* @see StringRedisTemplate
@@ -345,4 +348,24 @@ public interface StringRedisConnection extends RedisConnection {
* @return
*/
Cursor<StringTuple> zScan(String key, ScanOptions options);
/**
* @since 1.5
* @param key
* @param min
* @param max
* @return
*/
Set<byte[]> zRangeByScore(String key, String min, String max);
/**
* @since 1.5
* @param key
* @param min
* @param max
* @param offset
* @param count
* @return
*/
Set<byte[]> zRangeByScore(String key, String min, String max, long offset, long count);
}

View File

@@ -3163,4 +3163,42 @@ public class JedisConnection extends AbstractRedisConnection {
protected Jedis getJedis(RedisNode node) {
return new Jedis(node.getHost(), node.getPort());
}
@Override
public Set<byte[]> zRangeByScore(byte[] key, String min, String max) {
try {
String keyStr = new String(key, "UTF-8");
if (isPipelined()) {
pipeline(new JedisResult(pipeline.zrangeByScore(keyStr, min, max)));
return null;
}
if (isQueueing()) {
transaction(new JedisResult(transaction.zrangeByScore(keyStr, min, max)));
return null;
}
return JedisConverters.stringSetToByteSet().convert(jedis.zrangeByScore(keyStr, min, max));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
@Override
public Set<byte[]> zRangeByScore(byte[] key, String min, String max, long offset, long count) {
try {
String keyStr = new String(key, "UTF-8");
if (isPipelined()) {
pipeline(new JedisResult(pipeline.zrangeByScore(keyStr, min, max, (int) offset, (int) count)));
return null;
}
if (isQueueing()) {
transaction(new JedisResult(transaction.zrangeByScore(keyStr, min, max, (int) offset, (int) count)));
return null;
}
return JedisConverters.stringSetToByteSet().convert(jedis.zrangeByScore(keyStr, min, max, (int) offset, (int) count));
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
}

View File

@@ -1282,5 +1282,14 @@ public class JredisConnection extends AbstractRedisConnection {
public Cursor<Entry<byte[], byte[]>> hScan(byte[] key, ScanOptions options) {
throw new UnsupportedOperationException("'HSCAN' command is not uspported for jredis");
}
@Override
public Set<byte[]> zRangeByScore(byte[] key, String min, String max) {
throw new UnsupportedOperationException("'zRangeByScore' command is not uspported for jredis");
}
@Override
public Set<byte[]> zRangeByScore(byte[] key, String min, String max, long offset, long count) {
throw new UnsupportedOperationException("'zRangeByScore' command is not uspported for jredis");
}
}

View File

@@ -3616,4 +3616,44 @@ public class LettuceConnection extends AbstractRedisConnection {
}
}
@Override
public Set<byte[]> zRangeByScore(byte[] key, String min, String max) {
try {
if (isPipelined()) {
pipeline(new LettuceResult(getAsyncConnection().zrangebyscore(key, min, max),
LettuceConverters.bytesListToBytesSet()));
return null;
}
if (isQueueing()) {
transaction(new LettuceTxResult(getConnection().zrangebyscore(key, min, max),
LettuceConverters.bytesListToBytesSet()));
return null;
}
return LettuceConverters.toBytesSet(getConnection().zrangebyscore(key, min, max));
} catch (Exception ex) {
throw convertLettuceAccessException(ex);
}
}
@Override
public Set<byte[]> zRangeByScore(byte[] key, String min, String 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);
}
}
}

View File

@@ -2472,4 +2472,35 @@ public class SrpConnection extends AbstractRedisConnection {
return arrays.toArray();
}
@Override
public Set<byte[]> zRangeByScore(byte[] key, String min, String max) {
try {
String keyStr = new String(key, "UTF-8");
if (isPipelined()) {
pipeline(new SrpResult(pipeline.zrangebyscore(keyStr, min, max, null, EMPTY_PARAMS_ARRAY),
SrpConverters.repliesToBytesSet()));
return null;
}
return SrpConverters.toBytesSet(client.zrangebyscore(keyStr, min, max, null, EMPTY_PARAMS_ARRAY).data());
} catch (Exception ex) {
throw convertSrpAccessException(ex);
}
}
@Override
public Set<byte[]> zRangeByScore(byte[] key, String min, String max, long offset, long count) {
try {
String keyStr = new String(key, "UTF-8");
Object[] limit = limitParams(offset, count);
if (isPipelined()) {
pipeline(new SrpResult(pipeline.zrangebyscore(keyStr, min, max, null, limit), SrpConverters.repliesToBytesSet()));
return null;
}
return SrpConverters.toBytesSet(client.zrangebyscore(keyStr, min, max, null, limit).data());
} catch (Exception ex) {
throw convertSrpAccessException(ex);
}
}
}

View File

@@ -29,6 +29,8 @@ import org.springframework.data.redis.connection.RedisZSetCommands.Tuple;
*
* @author Costin Leau
* @author Christoph Strobl
* @author Thomas Darimont
* @author David Liu
*/
class DefaultZSetOperations<K, V> extends AbstractOperations<K, V> implements ZSetOperations<K, V> {
@@ -392,4 +394,32 @@ class DefaultZSetOperations<K, V> extends AbstractOperations<K, V> implements ZS
}
});
}
public Set<byte[]> rangeByScore(K key, final String min, final String max) {
final byte[] rawKey = rawKey(key);
Set<byte[]> rawValues = execute(new RedisCallback<Set<byte[]>>() {
public Set<byte[]> doInRedis(RedisConnection connection) {
return connection.zRangeByScore(rawKey, min, max);
}
}, true);
return rawValues;
}
public Set<byte[]> rangeByScore(K key, final String min, final String max, final long offset, final long count) {
final byte[] rawKey = rawKey(key);
Set<byte[]> rawValues = execute(new RedisCallback<Set<byte[]>>() {
public Set<byte[]> doInRedis(RedisConnection connection) {
return connection.zRangeByScore(rawKey, min, max, offset, count);
}
}, true);
return rawValues;
}
}

View File

@@ -35,6 +35,7 @@ import org.springframework.util.ObjectUtils;
/**
* @author Christoph Strobl
* @author Thomas Darimont
* @author David Liu
*/
public class RedisConnectionUnitTests {
@@ -790,5 +791,15 @@ public class RedisConnectionUnitTests {
public <T> T evalSha(byte[] scriptSha, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
return delegate.evalSha(scriptSha, returnType, numKeys, keysAndArgs);
}
@Override
public Set<byte[]> zRangeByScore(byte[] key, String min, String max) {
return delegate.zRangeByScore(key, min, max);
}
@Override
public Set<byte[]> zRangeByScore(byte[] key, String min, String max, long offset, long count) {
return delegate.zRangeByScore(key, min, max, offset, count);
}
}
}

View File

@@ -61,6 +61,7 @@ import redis.clients.jedis.JedisPoolConfig;
* @author Jennifer Hickey
* @author Thomas Darimont
* @author Christoph Strobl
* @author David Liu
*/
@RunWith(RelaxedJUnit4ClassRunner.class)
@ContextConfiguration
@@ -400,4 +401,19 @@ public class JedisConnectionIntegrationTests extends AbstractConnectionIntegrati
.sentinel("127.0.0.1", 26379).sentinel("127.0.0.1", 26380));
assertThat(connection.getSentinelConnection(), notNullValue());
}
/**
* @see DATAREDIS-106
*/
@Test
public void zRangeByScoreTest() {
connection.zAdd("myzset", 1, "one");
connection.zAdd("myzset", 2, "two");
connection.zAdd("myzset", 3, "three");
Set<byte[]> zRangeByScore = connection.zRangeByScore("myzset", "(1", "2");
assertEquals("two", new String(zRangeByScore.iterator().next()));
}
}

View File

@@ -22,6 +22,7 @@ import static org.springframework.data.redis.SpinBarrier.*;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import org.hamcrest.core.AllOf;
@@ -52,6 +53,7 @@ import com.lambdaworks.redis.RedisAsyncConnection;
* @author Jennifer Hickey
* @author Thomas Darimont
* @author Christoph Strobl
* @author David Liu
*/
@RunWith(RelaxedJUnit4ClassRunner.class)
@ContextConfiguration
@@ -311,5 +313,20 @@ public class LettuceConnectionIntegrationTests extends AbstractConnectionIntegra
assertEquals(Arrays.asList(new Object[] { "key1", "arg1" }),
Arrays.asList(new Object[] { new String(scriptResults.get(0)), new String(scriptResults.get(1)) }));
}
/**
* @see DATAREDIS-106
*/
@Test
public void zRangeByScoreTest() {
connection.zAdd("myzset", 1, "one");
connection.zAdd("myzset", 2, "two");
connection.zAdd("myzset", 3, "three");
Set<byte[]> zRangeByScore = connection.zRangeByScore("myzset", "(1", "2");
assertEquals("two", new String(zRangeByScore.iterator().next()));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2013 the original author or authors.
* Copyright 2011-2014 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.
@@ -20,6 +20,7 @@ import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import org.hamcrest.core.Is;
import org.hamcrest.core.IsInstanceOf;
@@ -40,6 +41,8 @@ import redis.reply.Reply;
*
* @author Costin Leau
* @author Jennifer Hickey
* @author Thomas Darimont
* @author David Liu
*/
@RunWith(RelaxedJUnit4ClassRunner.class)
@ContextConfiguration
@@ -117,4 +120,18 @@ public class SrpConnectionIntegrationTests extends AbstractConnectionIntegration
Arrays.asList(new Object[] { new String(scriptResults.get(0)), new String(scriptResults.get(1)) }));
}
/**
* @see DATAREDIS-106
*/
@Test
public void zRangeByScoreTest() {
connection.zAdd("myzset", 1, "one");
connection.zAdd("myzset", 2, "two");
connection.zAdd("myzset", 3, "three");
Set<byte[]> zRangeByScore = connection.zRangeByScore("myzset", "(1", "2");
Assert.assertEquals("two", new String(zRangeByScore.iterator().next()));
}
}