From 7d0a34a3dd588c94fa66f53a94c61d7da4b7f877 Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Fri, 12 Nov 2010 21:30:00 +0200 Subject: [PATCH] + updated RedisTemplate/Operations --- .../datastore/redis/core/ListOperations.java | 4 +- .../datastore/redis/core/RedisTemplate.java | 196 ++++++++++++++++-- .../datastore/redis/util/RedisList.java | 4 +- 3 files changed, 180 insertions(+), 24 deletions(-) diff --git a/spring-datastore-redis/src/main/java/org/springframework/datastore/redis/core/ListOperations.java b/spring-datastore-redis/src/main/java/org/springframework/datastore/redis/core/ListOperations.java index 8bcf32a55..930466d6b 100644 --- a/spring-datastore-redis/src/main/java/org/springframework/datastore/redis/core/ListOperations.java +++ b/spring-datastore-redis/src/main/java/org/springframework/datastore/redis/core/ListOperations.java @@ -44,7 +44,7 @@ public interface ListOperations { V rightPop(K key); - V blockingLeftPop(K key); + List blockingLeftPop(int timeout, K... keys); - V blockingRightPop(K key); + List blockingRightPop(int timeout, K... keys); } diff --git a/spring-datastore-redis/src/main/java/org/springframework/datastore/redis/core/RedisTemplate.java b/spring-datastore-redis/src/main/java/org/springframework/datastore/redis/core/RedisTemplate.java index f353b5e64..d4abb5cd8 100644 --- a/spring-datastore-redis/src/main/java/org/springframework/datastore/redis/core/RedisTemplate.java +++ b/spring-datastore-redis/src/main/java/org/springframework/datastore/redis/core/RedisTemplate.java @@ -19,6 +19,9 @@ import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; import org.springframework.datastore.redis.connection.RedisConnection; import org.springframework.datastore.redis.connection.RedisConnectionFactory; @@ -184,15 +187,39 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation return (key != null ? keySerializer.serialize(key) : null); } - private byte[] rawValue(V value) { + private byte[] rawValue(T value) { return (value != null ? valueSerializer.serialize(value) : null); } + private byte[][] rawKeys(K... keys) { + final byte[][] rawKeys = new byte[keys.length][]; + + for (int i = 0; i < keys.length; i++) { + rawKeys[i] = rawKey(keys[i]); + } + + return rawKeys; + } + + private List values(Collection rawValues) { + List values = new ArrayList(rawValues.size()); + for (byte[] bs : rawValues) { + values.add((V) valueSerializer.deserialize(bs)); + } + + return values; + } + // utility methods for the template internal methods - private abstract class DeserializingRedisCallback implements RedisCallback { + private abstract class ValueDeserializingRedisCallback implements RedisCallback { private K key; - public DeserializingRedisCallback(K key) { + public ValueDeserializingRedisCallback() { + this(null); + + } + + public ValueDeserializingRedisCallback(K key) { this.key = key; } @@ -226,26 +253,22 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation @Override public V get(final K key) { - return execute(new DeserializingRedisCallback(key) { - + return execute(new ValueDeserializingRedisCallback(key) { @Override protected byte[] inRedis(byte[] rawKey, RedisConnection connection) { return connection.get(rawKey); } - }, false); } @Override public V getAndSet(K key, V newValue) { final byte[] rawValue = rawValue(newValue); - return execute(new DeserializingRedisCallback(key) { - + return execute(new ValueDeserializingRedisCallback(key) { @Override protected byte[] inRedis(byte[] rawKey, RedisConnection connection) { return connection.getSet(rawKey, rawValue); } - }, false); } @@ -253,7 +276,6 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation public Integer increment(K key, final int delta) { final byte[] rawKey = rawKey(key); return execute(new RedisCallback() { - @Override public Integer doInRedis(RedisConnection connection) throws Exception { if (delta == 1) { @@ -275,7 +297,7 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation @Override public ListOperations listOps() { - throw new UnsupportedOperationException(); + return new DefaultListOperations(); } @Override @@ -286,27 +308,20 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation @Override public void set(K key, V value) { final byte[] rawValue = rawValue(value); - execute(new DeserializingRedisCallback(key) { - + execute(new ValueDeserializingRedisCallback(key) { @Override protected byte[] inRedis(byte[] rawKey, RedisConnection connection) { connection.set(rawKey, rawValue); return null; } - }, false); } @Override public void watch(K... keys) { - final byte[][] rawKeys = new byte[keys.length][]; - - for (int i = 0; i < keys.length; i++) { - rawKeys[i] = rawKey(keys[i]); - } + final byte[][] rawKeys = rawKeys(keys); execute(new RedisCallback() { - @Override public Object doInRedis(RedisConnection connection) throws Exception { connection.watch(rawKeys); @@ -314,4 +329,145 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation } }, false); } + + // + // List operations + // + + private class DefaultListOperations implements ListOperations { + + @Override + public List blockingLeftPop(final int timeout, K... keys) { + final byte[][] rawKeys = rawKeys(keys); + + return execute(new RedisCallback>() { + @Override + public List doInRedis(RedisConnection connection) throws Exception { + return values(connection.bLPop(timeout, rawKeys)); + } + }, false); + } + + @Override + public List blockingRightPop(final int timeout, K... keys) { + final byte[][] rawKeys = rawKeys(keys); + return execute(new RedisCallback>() { + @Override + public List doInRedis(RedisConnection connection) throws Exception { + return values(connection.bRPop(timeout, rawKeys)); + } + }, false); + } + + @Override + public V index(K key, final int index) { + return execute(new ValueDeserializingRedisCallback(key) { + @Override + protected byte[] inRedis(byte[] rawKey, RedisConnection connection) { + return connection.lIndex(rawKey, index); + } + }, false); + } + + @Override + public V leftPop(K key) { + return execute(new ValueDeserializingRedisCallback(key) { + @Override + protected byte[] inRedis(byte[] rawKey, RedisConnection connection) { + return connection.lPop(rawKey); + } + }, false); + } + + @Override + public Integer leftPush(K key, V value) { + final byte[] rawKey = rawKey(key); + final byte[] rawValue = rawValue(value); + return execute(new RedisCallback() { + @Override + public Integer doInRedis(RedisConnection connection) throws Exception { + return connection.lPush(rawKey, rawValue); + } + }, false); + } + + @Override + public Integer length(K key) { + final byte[] rawKey = rawKey(key); + return execute(new RedisCallback() { + @Override + public Integer doInRedis(RedisConnection connection) throws Exception { + return connection.lLen(rawKey); + } + }, false); + } + + @Override + public List range(K key, final int start, final int end) { + final byte[] rawKey = rawKey(key); + return execute(new RedisCallback>() { + @Override + public List doInRedis(RedisConnection connection) throws Exception { + return values(connection.lRange(rawKey, start, end)); + } + }, false); + } + + @Override + public Integer remove(K key, final int count, Object value) { + final byte[] rawKey = rawKey(key); + final byte[] rawValue = rawValue(value); + return execute(new RedisCallback() { + @Override + public Integer doInRedis(RedisConnection connection) throws Exception { + return connection.lRem(rawKey, count, rawValue); + } + }, false); + } + + @Override + public V rightPop(K key) { + return execute(new ValueDeserializingRedisCallback(key) { + @Override + protected byte[] inRedis(byte[] rawKey, RedisConnection connection) { + return connection.rPop(rawKey); + } + }, false); + } + + @Override + public Integer rightPush(K key, V value) { + final byte[] rawKey = rawKey(key); + final byte[] rawValue = rawValue(value); + return execute(new RedisCallback() { + @Override + public Integer doInRedis(RedisConnection connection) throws Exception { + return connection.rPush(rawKey, rawValue); + } + }, false); + } + + @Override + public void set(K key, final int index, V value) { + final byte[] rawValue = rawValue(value); + execute(new ValueDeserializingRedisCallback(key) { + @Override + protected byte[] inRedis(byte[] rawKey, RedisConnection connection) { + connection.lSet(rawKey, index, rawValue); + return null; + } + }, false); + } + + @Override + public void trim(K key, final int start, final int end) { + execute(new ValueDeserializingRedisCallback(key) { + @Override + protected byte[] inRedis(byte[] rawKey, RedisConnection connection) { + connection.lTrim(rawKey, start, end); + return null; + } + }, false); + } + } } \ No newline at end of file diff --git a/spring-datastore-redis/src/main/java/org/springframework/datastore/redis/util/RedisList.java b/spring-datastore-redis/src/main/java/org/springframework/datastore/redis/util/RedisList.java index 492eef424..c49ec8ad2 100644 --- a/spring-datastore-redis/src/main/java/org/springframework/datastore/redis/util/RedisList.java +++ b/spring-datastore-redis/src/main/java/org/springframework/datastore/redis/util/RedisList.java @@ -20,11 +20,11 @@ import java.util.Queue; /** * Redis extension for the {@link List} contract. Supports {@link List} specific - * operations backed by Redis commands. + * operations backed by Redis operations. * * @author Costin Leau */ -public interface RedisList extends RedisStore, List, Queue { +public interface RedisList extends RedisStore, List, Queue { List range(int start, int end);