From f4feb8b993f0140bb09855f8292a66bf479c502f Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Thu, 21 Apr 2011 21:49:49 +0300 Subject: [PATCH 01/13] + add bug fix to key rename --- .../data/keyvalue/redis/core/DefaultBoundKeyOperations.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundKeyOperations.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundKeyOperations.java index 105c6e48b..b3ac53db4 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundKeyOperations.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundKeyOperations.java @@ -66,7 +66,9 @@ abstract class DefaultBoundKeyOperations implements BoundKeyOperations { @Override public void rename(K newKey) { - ops.rename(key, newKey); + if (ops.hasKey(key)) { + ops.rename(key, newKey); + } key = newKey; } } \ No newline at end of file From e55f1a745beef8643d9238a0f15bf4c9b2f76275 Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Fri, 22 Apr 2011 17:49:29 +0300 Subject: [PATCH 02/13] DATAKV-68 + merge channel and pattern into topic in the listener namespace --- .../config/RedisListenerContainerParser.java | 21 +++++-------------- .../keyvalue/redis/listener/ChannelTopic.java | 6 +++--- .../redis/config/spring-redis-1.0.xsd | 15 ++++--------- .../data/keyvalue/redis/config/namespace.xml | 6 +++--- src/docbkx/reference/redis-messaging.xml | 4 ++-- 5 files changed, 17 insertions(+), 35 deletions(-) diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/config/RedisListenerContainerParser.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/config/RedisListenerContainerParser.java index 12fd192fd..8dca98e68 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/config/RedisListenerContainerParser.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/config/RedisListenerContainerParser.java @@ -117,26 +117,15 @@ class RedisListenerContainerParser extends AbstractSimpleBeanDefinitionParser { // assemble topics Collection topics = new ArrayList(); - // get channels - String channels = element.getAttribute("channel"); - if (StringUtils.hasText(channels)) { - String[] array = StringUtils.delimitedListToStringArray(channels, " "); + // get topic + String xTopics = element.getAttribute("topic"); + if (StringUtils.hasText(xTopics)) { + String[] array = StringUtils.delimitedListToStringArray(xTopics, " "); for (String string : array) { - topics.add(new ChannelTopic(string)); + topics.add(string.contains("*") ? new PatternTopic(string) : new ChannelTopic(string)); } } - - // get patterns - String patterns = element.getAttribute("pattern"); - if (StringUtils.hasText(patterns)) { - String[] array = StringUtils.delimitedListToStringArray(patterns, " "); - - for (String string : array) { - topics.add(new PatternTopic(string)); - } - } - ret[0] = builder.getBeanDefinition(); ret[1] = topics; diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/listener/ChannelTopic.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/listener/ChannelTopic.java index 654c34b7a..17ebda41a 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/listener/ChannelTopic.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/listener/ChannelTopic.java @@ -16,7 +16,7 @@ package org.springframework.data.keyvalue.redis.listener; /** - * Topic describing a channel. + * Channel topic implementation (maps to a Redis channel). * * @author Costin Leau */ @@ -34,9 +34,9 @@ public class ChannelTopic implements Topic { } /** - * Returns the channel name. + * Returns the topic name. * - * @return channel name + * @return topic name */ public String getTopic() { return channelName; diff --git a/spring-data-redis/src/main/resources/org/springframework/data/keyvalue/redis/config/spring-redis-1.0.xsd b/spring-data-redis/src/main/resources/org/springframework/data/keyvalue/redis/config/spring-redis-1.0.xsd index dea12ea92..59c815d6e 100644 --- a/spring-data-redis/src/main/resources/org/springframework/data/keyvalue/redis/config/spring-redis-1.0.xsd +++ b/spring-data-redis/src/main/resources/org/springframework/data/keyvalue/redis/config/spring-redis-1.0.xsd @@ -110,19 +110,12 @@ and stop as soon as possible. - + - - - - - diff --git a/spring-data-redis/src/test/resources/org/springframework/data/keyvalue/redis/config/namespace.xml b/spring-data-redis/src/test/resources/org/springframework/data/keyvalue/redis/config/namespace.xml index 91a7cc2f3..ab17a299e 100644 --- a/spring-data-redis/src/test/resources/org/springframework/data/keyvalue/redis/config/namespace.xml +++ b/spring-data-redis/src/test/resources/org/springframework/data/keyvalue/redis/config/namespace.xml @@ -14,10 +14,10 @@ - + - - + + diff --git a/src/docbkx/reference/redis-messaging.xml b/src/docbkx/reference/redis-messaging.xml index b88d4ffac..37f60be0e 100644 --- a/src/docbkx/reference/redis-messaging.xml +++ b/src/docbkx/reference/redis-messaging.xml @@ -157,7 +157,7 @@ template.convertAndSend("hello!", "world");]]> <!-- the default ConnectionFactory --> <redis:listener-container> <!-- the method attribute can be skipped as the default method name is "handleMessage" --> - <redis:listener ref="listener" method="handleMessage" channel="chatroom" /> + <redis:listener ref="listener" method="handleMessage" topic="chatroom" /> </redis:listener-container> <bean class="redisexample.DefaultMessageDelegate"/> @@ -179,7 +179,7 @@ template.convertAndSend("hello!", "world");]]> <bean id="redisContainer" class="org.springframework.data.keyvalue.redis.listener.RedisMessageListenerContainer"> <property name="connectionFactory" ref="connectionFactory"/> <property name="messageListeners"> - <!-- map of listeners and their associated topics (channels or topics) --> + <!-- map of listeners and their associated topics (channels or/and patterns) --> <map> <entry key-ref="messageListener"> <bean class="org.springframework.data.keyvalue.redis.listener.ChannelTopic"> From 623f1a0c97cfb42db24db298f477cfd67423169a Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Thu, 28 Apr 2011 17:44:31 +0300 Subject: [PATCH 03/13] update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 54ef9a8e5..7eacd8dd7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .DS_Store target build +bin .gradle .springBeans .ant-targets-build.xml From ce59e74b72203e4db3cf0803ac2d9353fb8f982e Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Thu, 28 Apr 2011 17:56:56 +0300 Subject: [PATCH 04/13] DATAKV-68 + add pattern vs channel example inside docs --- src/docbkx/reference/redis-messaging.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/docbkx/reference/redis-messaging.xml b/src/docbkx/reference/redis-messaging.xml index 37f60be0e..10807cbf7 100644 --- a/src/docbkx/reference/redis-messaging.xml +++ b/src/docbkx/reference/redis-messaging.xml @@ -164,6 +164,7 @@ template.convertAndSend("hello!", "world");]]> ... <beans> + The listener topic can be either a channel (e.g. topic="chatroom") or a pattern (e.g. topic="*room") The example above uses the Redis namespace to declare the message listener container and automatically register the POJOs as listeners. The full blown, beans definition is displayed below: From cb8fc22c450d1513feaf92d491cf1679d1ff053b Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Thu, 28 Apr 2011 18:04:45 +0300 Subject: [PATCH 05/13] + add dedicated section on configurating RJC --- src/docbkx/reference/redis.xml | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/docbkx/reference/redis.xml b/src/docbkx/reference/redis.xml index 57f27b13a..24c1bb220 100644 --- a/src/docbkx/reference/redis.xml +++ b/src/docbkx/reference/redis.xml @@ -20,7 +20,7 @@ Redis Requirements SDKV requires Redis 2.0 or above (Redis 2.2 is recommended) and Java SE 6.0 or above. In terms of language bindings (or connectors), SDKV integrates with Jedis, - JRedis and RJC, three popular open source Java libraries for Redis. + JRedis and RJC, three popular open source Java libraries for Redis. If you are aware of any other connector that we should be integrating is, please send us feedback. @@ -146,6 +146,36 @@ + +
+ Configuring RJC connector + + RJC is the third, open-source connector supported by SDKV through the + org.springframework.data.keyvalue.redis.connection.rjc package. + + Similar to the other connectors, a typical RJC configuration can looks like this: + + + + + +]]> + + As one can note, the configuration is quite similar to the Jredis or Jedis one. + + Currently, RJC does not have support for binary keys. This forces the RjcConnection to perform encoding internally + (through base64 schema). In practice, this means it's safe to read/write arbitrary data however + the Redis key stored values will differ from the decoded ones, even in the simplest cases, since everything (no matter the format) is encoded. This will not be + the case for Redis values. + This issue is currently being addressed in the RJC project and once fixed, will be incorporated by Spring Data Redis. + + +
From 3c0bccf1d48f65c5b69cd47d386854e57f9fd440 Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Thu, 28 Apr 2011 19:03:15 +0300 Subject: [PATCH 06/13] DATAKV-67 + removed ability to pass in custom template since that's not the case (as the backing format is predefined and custom serialization is not an option) --- .../support/atomic/RedisAtomicInteger.java | 37 ------------------- .../redis/support/atomic/RedisAtomicLong.java | 36 ------------------ 2 files changed, 73 deletions(-) diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/atomic/RedisAtomicInteger.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/atomic/RedisAtomicInteger.java index 79e5b523e..ca33798ba 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/atomic/RedisAtomicInteger.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/atomic/RedisAtomicInteger.java @@ -87,43 +87,6 @@ public class RedisAtomicInteger extends Number implements Serializable, BoundKey } } - /** - * Constructs a new RedisAtomicInteger instance. Uses as initial value - * the data from the backing store (sets the counter to 0 if no value is found). - * - * Use {@link #RedisAtomicInteger(String, RedisOperations, int)} to set the counter to a certain value - * as an alternative constructor or {@link #set(int)}. - * - * Note that integers need to be properly serialized so that Redis can recognized the values as numeric and thus modify their value. - * - * @param redisCounter - * @param operations - */ - public RedisAtomicInteger(String redisCounter, RedisOperations operations) { - this.key = redisCounter; - this.operations = operations.opsForValue(); - this.generalOps = operations; - if (this.operations.get(redisCounter) == null) { - set(0); - } - } - - /** - * Constructs a new RedisAtomicInteger instance with the given initial value. - * - * Note that integers need to be properly serialized so that Redis can recognized the values as numeric and thus modify their value. - * - * @param redisCounter - * @param operations - * @param initialValue - */ - public RedisAtomicInteger(String redisCounter, RedisOperations operations, int initialValue) { - this.key = redisCounter; - this.operations = operations.opsForValue(); - this.generalOps = operations; - this.operations.set(redisCounter, initialValue); - } - /** * Get the current value. * diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/atomic/RedisAtomicLong.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/atomic/RedisAtomicLong.java index 9da634b3e..36502c489 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/atomic/RedisAtomicLong.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/atomic/RedisAtomicLong.java @@ -87,42 +87,6 @@ public class RedisAtomicLong extends Number implements Serializable, BoundKeyOpe } } - /** - * Constructs a new RedisAtomicLong instance. Uses as initial value - * the data from the backing store (sets the counter to 0 if no value is found). - * - * Use {@link #RedisAtomicLong(String, RedisOperations, long)} to set the counter to a certain value - * as an alternative constructor or {@link #set(long)}. - * - * Note that longs need to be properly serialized so that Redis can recognized the values as numeric and thus modify their value. - * - * @param redisCounter - * @param operations - */ - public RedisAtomicLong(String redisCounter, RedisOperations operations) { - this.key = redisCounter; - this.operations = operations.opsForValue(); - this.generalOps = operations; - if (this.operations.get(redisCounter) == null) { - set(0); - } - } - - /** - * Constructs a new RedisAtomicLong instance with the given initial value. - * - * Note that longs need to be properly serialized so that Redis can recognized the values as numeric and thus modify their value. - * - * @param redisCounter - * @param operations - * @param initialValue - */ - public RedisAtomicLong(String redisCounter, RedisOperations operations, long initialValue) { - this.key = redisCounter; - this.operations = operations.opsForValue(); - this.operations.set(redisCounter, initialValue); - } - /** * Gets the current value. * From 35dc5f198aaaa70a3cefe21e2323ff474c95892a Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Thu, 28 Apr 2011 19:05:18 +0300 Subject: [PATCH 07/13] - remove ConnectionFactory constructor since its use was misinterpreted pretty much all the time (users assumed no initialization took place when it was quite the opposite). + constructor remained in place for StringRedisTemplate --- .../keyvalue/redis/core/RedisTemplate.java | 29 +++++++-------- .../redis/core/StringRedisTemplate.java | 4 ++- .../redis/listener/PubSubTestParams.java | 8 +++-- .../collections/CollectionTestParams.java | 36 +++++++++++++------ .../support/collections/RedisMapTests.java | 7 ++-- .../collections/RedisPropertiesTests.java | 6 ++-- 6 files changed, 54 insertions(+), 36 deletions(-) diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/RedisTemplate.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/RedisTemplate.java index eb9c1d398..cdf6f4364 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/RedisTemplate.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/RedisTemplate.java @@ -87,18 +87,6 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation public RedisTemplate() { } - /** - * Constructs a new RedisTemplate instance and automatically initializes the template. - * If other parameters need to be set, it is recommended to use {@link #setConnectionFactory(RedisConnectionFactory)} instead. - * - * @param connectionFactory connection factory for creating new connections - */ - public RedisTemplate(RedisConnectionFactory connectionFactory) { - this.setConnectionFactory(connectionFactory); - afterPropertiesSet(); - } - - @Override public void afterPropertiesSet() { super.afterPropertiesSet(); @@ -126,11 +114,6 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation if (defaultUsed) { Assert.notNull(defaultSerializer, "default serializer null and not all serializers initialized"); } - - valueOps = new DefaultValueOperations(this); - listOps = new DefaultListOperations(this); - setOps = new DefaultSetOperations(this); - zSetOps = new DefaultZSetOperations(this); } @Override @@ -754,11 +737,17 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation @Override public ValueOperations opsForValue() { + if (valueOps == null) { + valueOps = new DefaultValueOperations(this); + } return valueOps; } @Override public ListOperations opsForList() { + if (listOps == null) { + listOps = new DefaultListOperations(this); + } return listOps; } @@ -774,6 +763,9 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation @Override public SetOperations opsForSet() { + if (setOps == null) { + setOps = new DefaultSetOperations(this); + } return setOps; } @@ -784,6 +776,9 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation @Override public ZSetOperations opsForZSet() { + if (zSetOps == null) { + zSetOps = new DefaultZSetOperations(this); + } return zSetOps; } diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/StringRedisTemplate.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/StringRedisTemplate.java index 90b22c2d0..29db41807 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/StringRedisTemplate.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/StringRedisTemplate.java @@ -36,6 +36,8 @@ public class StringRedisTemplate extends RedisTemplate { /** * Constructs a new StringRedisTemplate instance. + * {@link #setConnectionFactory(RedisConnectionFactory)} and {@link #afterPropertiesSet()} still need to be called. + * */ public StringRedisTemplate() { RedisSerializer stringSerializer = new StringRedisSerializer(); @@ -46,7 +48,7 @@ public class StringRedisTemplate extends RedisTemplate { } /** - * Constructs a new StringRedisTemplate instance. + * Constructs a new StringRedisTemplate instance ready to be used. * * @param connectionFactory connection factory for creating new connections */ diff --git a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/listener/PubSubTestParams.java b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/listener/PubSubTestParams.java index cba742c7f..bac0d731b 100644 --- a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/listener/PubSubTestParams.java +++ b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/listener/PubSubTestParams.java @@ -47,7 +47,9 @@ public class PubSubTestParams { jedisConnFactory.afterPropertiesSet(); RedisTemplate stringTemplate = new StringRedisTemplate(jedisConnFactory); - RedisTemplate personTemplate = new RedisTemplate(jedisConnFactory); + RedisTemplate personTemplate = new RedisTemplate(); + personTemplate.setConnectionFactory(jedisConnFactory); + personTemplate.afterPropertiesSet(); // create RJC @@ -58,7 +60,9 @@ public class PubSubTestParams { rjcConnFactory.afterPropertiesSet(); RedisTemplate stringTemplateRJC = new StringRedisTemplate(rjcConnFactory); - RedisTemplate personTemplateRJC = new RedisTemplate(rjcConnFactory); + RedisTemplate personTemplateRJC = new RedisTemplate(); + personTemplateRJC.setConnectionFactory(rjcConnFactory); + personTemplateRJC.afterPropertiesSet(); return Arrays.asList(new Object[][] { { stringFactory, stringTemplate }, { personFactory, personTemplate }, diff --git a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/collections/CollectionTestParams.java b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/collections/CollectionTestParams.java index e320a974e..0802607e1 100644 --- a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/collections/CollectionTestParams.java +++ b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/collections/CollectionTestParams.java @@ -24,6 +24,7 @@ import org.springframework.data.keyvalue.redis.connection.jedis.JedisConnectionF import org.springframework.data.keyvalue.redis.connection.jredis.JredisConnectionFactory; import org.springframework.data.keyvalue.redis.connection.rjc.RjcConnectionFactory; import org.springframework.data.keyvalue.redis.core.RedisTemplate; +import org.springframework.data.keyvalue.redis.core.StringRedisTemplate; import org.springframework.data.keyvalue.redis.serializer.JacksonJsonRedisSerializer; import org.springframework.data.keyvalue.redis.serializer.OxmSerializer; import org.springframework.oxm.xstream.XStreamMarshaller; @@ -56,20 +57,26 @@ public abstract class CollectionTestParams { jedisConnFactory.afterPropertiesSet(); - RedisTemplate stringTemplate = new RedisTemplate(jedisConnFactory); - RedisTemplate personTemplate = new RedisTemplate(jedisConnFactory); + RedisTemplate stringTemplate = new StringRedisTemplate(jedisConnFactory); + RedisTemplate personTemplate = new RedisTemplate(); + personTemplate.setConnectionFactory(jedisConnFactory); + personTemplate.afterPropertiesSet(); RedisTemplate xstreamStringTemplate = new RedisTemplate(); xstreamStringTemplate.setConnectionFactory(jedisConnFactory); xstreamStringTemplate.setDefaultSerializer(serializer); xstreamStringTemplate.afterPropertiesSet(); - RedisTemplate xstreamPersonTemplate = new RedisTemplate(jedisConnFactory); + RedisTemplate xstreamPersonTemplate = new RedisTemplate(); + xstreamPersonTemplate.setConnectionFactory(jedisConnFactory); xstreamPersonTemplate.setValueSerializer(serializer); + xstreamPersonTemplate.afterPropertiesSet(); // json - RedisTemplate jsonPersonTemplate = new RedisTemplate(jedisConnFactory); + RedisTemplate jsonPersonTemplate = new RedisTemplate(); + jsonPersonTemplate.setConnectionFactory(jedisConnFactory); jsonPersonTemplate.setValueSerializer(jsonSerializer); + jsonPersonTemplate.afterPropertiesSet(); // jredis JredisConnectionFactory jredisConnFactory = new JredisConnectionFactory(); @@ -80,18 +87,25 @@ public abstract class CollectionTestParams { jredisConnFactory.afterPropertiesSet(); - RedisTemplate stringTemplateJR = new RedisTemplate(jredisConnFactory); - RedisTemplate personTemplateJR = new RedisTemplate(jredisConnFactory); + RedisTemplate stringTemplateJR = new StringRedisTemplate(jredisConnFactory); + RedisTemplate personTemplateJR = new RedisTemplate(); + personTemplateJR.setConnectionFactory(jredisConnFactory); + personTemplateJR.afterPropertiesSet(); RedisTemplate xstreamStringTemplateJR = new RedisTemplate(); xstreamStringTemplateJR.setConnectionFactory(jredisConnFactory); xstreamStringTemplateJR.setDefaultSerializer(serializer); xstreamStringTemplateJR.afterPropertiesSet(); - RedisTemplate xstreamPersonTemplateJR = new RedisTemplate(jredisConnFactory); + RedisTemplate xstreamPersonTemplateJR = new RedisTemplate(); xstreamPersonTemplateJR.setValueSerializer(serializer); - RedisTemplate jsonPersonTemplateJR = new RedisTemplate(jredisConnFactory); + xstreamPersonTemplateJR.setConnectionFactory(jredisConnFactory); + xstreamPersonTemplateJR.afterPropertiesSet(); + + RedisTemplate jsonPersonTemplateJR = new RedisTemplate(); jsonPersonTemplate.setValueSerializer(jsonSerializer); + jsonPersonTemplate.setConnectionFactory(jredisConnFactory); + jsonPersonTemplate.afterPropertiesSet(); // rjc @@ -101,8 +115,10 @@ public abstract class CollectionTestParams { rjcConnFactory.setHostName(SettingsUtils.getHost()); rjcConnFactory.afterPropertiesSet(); - RedisTemplate stringTemplateRJC = new RedisTemplate(rjcConnFactory); - RedisTemplate personTemplateRJC = new RedisTemplate(rjcConnFactory); + RedisTemplate stringTemplateRJC = new StringRedisTemplate(rjcConnFactory); + RedisTemplate personTemplateRJC = new RedisTemplate(); + personTemplateRJC.setConnectionFactory(rjcConnFactory); + personTemplateRJC.afterPropertiesSet(); RedisTemplate xstreamStringTemplateRJC = new RedisTemplate(); xstreamStringTemplateRJC.setConnectionFactory(rjcConnFactory); diff --git a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/collections/RedisMapTests.java b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/collections/RedisMapTests.java index 12efc9fc9..a2d9e449b 100644 --- a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/collections/RedisMapTests.java +++ b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/collections/RedisMapTests.java @@ -25,6 +25,7 @@ import org.springframework.data.keyvalue.redis.connection.jedis.JedisConnectionF import org.springframework.data.keyvalue.redis.connection.jredis.JredisConnectionFactory; import org.springframework.data.keyvalue.redis.connection.rjc.RjcConnectionFactory; import org.springframework.data.keyvalue.redis.core.RedisTemplate; +import org.springframework.data.keyvalue.redis.core.StringRedisTemplate; import org.springframework.data.keyvalue.redis.serializer.JacksonJsonRedisSerializer; import org.springframework.data.keyvalue.redis.serializer.OxmSerializer; import org.springframework.oxm.xstream.XStreamMarshaller; @@ -71,7 +72,7 @@ public class RedisMapTests extends AbstractRedisMapTests { jedisConnFactory.afterPropertiesSet(); - RedisTemplate genericTemplate = new RedisTemplate(jedisConnFactory); + RedisTemplate genericTemplate = new StringRedisTemplate(jedisConnFactory); RedisTemplate xstreamGenericTemplate = new RedisTemplate(); xstreamGenericTemplate.setConnectionFactory(jedisConnFactory); @@ -92,7 +93,7 @@ public class RedisMapTests extends AbstractRedisMapTests { jredisConnFactory.setHostName(SettingsUtils.getHost()); jredisConnFactory.afterPropertiesSet(); - RedisTemplate genericTemplateJR = new RedisTemplate(jredisConnFactory); + RedisTemplate genericTemplateJR = new StringRedisTemplate(jredisConnFactory); RedisTemplate xGenericTemplateJR = new RedisTemplate(); xGenericTemplateJR.setConnectionFactory(jredisConnFactory); xGenericTemplateJR.setDefaultSerializer(serializer); @@ -114,7 +115,7 @@ public class RedisMapTests extends AbstractRedisMapTests { rjcConnFactory.setHostName(SettingsUtils.getHost()); rjcConnFactory.afterPropertiesSet(); - RedisTemplate genericTemplateRJC = new RedisTemplate(jredisConnFactory); + RedisTemplate genericTemplateRJC = new StringRedisTemplate(jredisConnFactory); RedisTemplate xGenericTemplateRJC = new RedisTemplate(); xGenericTemplateRJC.setConnectionFactory(rjcConnFactory); xGenericTemplateRJC.setDefaultSerializer(serializer); diff --git a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/collections/RedisPropertiesTests.java b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/collections/RedisPropertiesTests.java index 8053fde02..b8e058e05 100644 --- a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/collections/RedisPropertiesTests.java +++ b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/collections/RedisPropertiesTests.java @@ -233,7 +233,7 @@ public class RedisPropertiesTests extends RedisMapTests { jedisConnFactory.afterPropertiesSet(); - RedisTemplate genericTemplate = new RedisTemplate(jedisConnFactory); + RedisTemplate genericTemplate = new StringRedisTemplate(jedisConnFactory); RedisTemplate xstreamGenericTemplate = new RedisTemplate(); xstreamGenericTemplate.setConnectionFactory(jedisConnFactory); @@ -254,7 +254,7 @@ public class RedisPropertiesTests extends RedisMapTests { jredisConnFactory.setHostName(SettingsUtils.getHost()); jredisConnFactory.afterPropertiesSet(); - RedisTemplate genericTemplateJR = new RedisTemplate(jredisConnFactory); + RedisTemplate genericTemplateJR = new StringRedisTemplate(jredisConnFactory); RedisTemplate xGenericTemplateJR = new RedisTemplate(); xGenericTemplateJR.setConnectionFactory(jredisConnFactory); xGenericTemplateJR.setDefaultSerializer(serializer); @@ -276,7 +276,7 @@ public class RedisPropertiesTests extends RedisMapTests { rjcConnFactory.setHostName(SettingsUtils.getHost()); rjcConnFactory.afterPropertiesSet(); - RedisTemplate genericTemplateRJC = new RedisTemplate(jredisConnFactory); + RedisTemplate genericTemplateRJC = new StringRedisTemplate(jredisConnFactory); RedisTemplate xGenericTemplateRJC = new RedisTemplate(); xGenericTemplateRJC.setConnectionFactory(rjcConnFactory); xGenericTemplateRJC.setDefaultSerializer(serializer); From 107badf522055667848b04d45f53bdf2fc66ce38 Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Mon, 2 May 2011 16:36:40 +0300 Subject: [PATCH 08/13] fix some init errors from last commit --- spring-data-redis/.classpath | 2 +- .../collections/CollectionTestParams.java | 6 +++--- .../support/collections/RedisMapTests.java | 17 +++++++++++------ 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/spring-data-redis/.classpath b/spring-data-redis/.classpath index db8601f3f..f05397d51 100644 --- a/spring-data-redis/.classpath +++ b/spring-data-redis/.classpath @@ -6,6 +6,6 @@ - + diff --git a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/collections/CollectionTestParams.java b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/collections/CollectionTestParams.java index 0802607e1..4464c94ae 100644 --- a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/collections/CollectionTestParams.java +++ b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/collections/CollectionTestParams.java @@ -103,9 +103,9 @@ public abstract class CollectionTestParams { xstreamPersonTemplateJR.afterPropertiesSet(); RedisTemplate jsonPersonTemplateJR = new RedisTemplate(); - jsonPersonTemplate.setValueSerializer(jsonSerializer); - jsonPersonTemplate.setConnectionFactory(jredisConnFactory); - jsonPersonTemplate.afterPropertiesSet(); + jsonPersonTemplateJR.setValueSerializer(jsonSerializer); + jsonPersonTemplateJR.setConnectionFactory(jredisConnFactory); + jsonPersonTemplateJR.afterPropertiesSet(); // rjc diff --git a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/collections/RedisMapTests.java b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/collections/RedisMapTests.java index a2d9e449b..e9807ef68 100644 --- a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/collections/RedisMapTests.java +++ b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/support/collections/RedisMapTests.java @@ -25,7 +25,6 @@ import org.springframework.data.keyvalue.redis.connection.jedis.JedisConnectionF import org.springframework.data.keyvalue.redis.connection.jredis.JredisConnectionFactory; import org.springframework.data.keyvalue.redis.connection.rjc.RjcConnectionFactory; import org.springframework.data.keyvalue.redis.core.RedisTemplate; -import org.springframework.data.keyvalue.redis.core.StringRedisTemplate; import org.springframework.data.keyvalue.redis.serializer.JacksonJsonRedisSerializer; import org.springframework.data.keyvalue.redis.serializer.OxmSerializer; import org.springframework.oxm.xstream.XStreamMarshaller; @@ -66,13 +65,13 @@ public class RedisMapTests extends AbstractRedisMapTests { JedisConnectionFactory jedisConnFactory = new JedisConnectionFactory(); jedisConnFactory.setUsePool(false); - jedisConnFactory.setPort(SettingsUtils.getPort()); jedisConnFactory.setHostName(SettingsUtils.getHost()); - jedisConnFactory.afterPropertiesSet(); - RedisTemplate genericTemplate = new StringRedisTemplate(jedisConnFactory); + RedisTemplate genericTemplate = new RedisTemplate(); + genericTemplate.setConnectionFactory(jedisConnFactory); + genericTemplate.afterPropertiesSet(); RedisTemplate xstreamGenericTemplate = new RedisTemplate(); xstreamGenericTemplate.setConnectionFactory(jedisConnFactory); @@ -93,7 +92,10 @@ public class RedisMapTests extends AbstractRedisMapTests { jredisConnFactory.setHostName(SettingsUtils.getHost()); jredisConnFactory.afterPropertiesSet(); - RedisTemplate genericTemplateJR = new StringRedisTemplate(jredisConnFactory); + RedisTemplate genericTemplateJR = new RedisTemplate(); + genericTemplateJR.setConnectionFactory(jredisConnFactory); + genericTemplateJR.afterPropertiesSet(); + RedisTemplate xGenericTemplateJR = new RedisTemplate(); xGenericTemplateJR.setConnectionFactory(jredisConnFactory); xGenericTemplateJR.setDefaultSerializer(serializer); @@ -115,7 +117,10 @@ public class RedisMapTests extends AbstractRedisMapTests { rjcConnFactory.setHostName(SettingsUtils.getHost()); rjcConnFactory.afterPropertiesSet(); - RedisTemplate genericTemplateRJC = new StringRedisTemplate(jredisConnFactory); + RedisTemplate genericTemplateRJC = new RedisTemplate(); + genericTemplateRJC.setConnectionFactory(rjcConnFactory); + genericTemplateRJC.afterPropertiesSet(); + RedisTemplate xGenericTemplateRJC = new RedisTemplate(); xGenericTemplateRJC.setConnectionFactory(rjcConnFactory); xGenericTemplateRJC.setDefaultSerializer(serializer); From 34390fe9caf18c046d34f8a69eb8ac27283a2ed2 Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Wed, 22 Jun 2011 19:56:39 +0300 Subject: [PATCH 09/13] + upgrade to Jedis 2.0.0 (first attempt) --- spring-data-redis/pom.xml | 4 +- .../connection/jedis/JedisConnection.java | 127 +++++++++--------- .../redis/connection/jedis/JedisUtils.java | 12 ++ 3 files changed, 81 insertions(+), 62 deletions(-) diff --git a/spring-data-redis/pom.xml b/spring-data-redis/pom.xml index bdb8330c0..f90ef76cd 100644 --- a/spring-data-redis/pom.xml +++ b/spring-data-redis/pom.xml @@ -15,9 +15,9 @@ "[3.0.0, 4.0.0)" 03122010 - 1.5.2 + 2.0.0 0.6.4 - "[1.0.0,2.0.0)" + "[2.0.0,2.0.0]" "[1.6, 2.0.0)" "[0.6.4, 0.6.4]" diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jedis/JedisConnection.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jedis/JedisConnection.java index 0d751765a..25c4b9dc6 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jedis/JedisConnection.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jedis/JedisConnection.java @@ -40,7 +40,6 @@ import redis.clients.jedis.BinaryTransaction; import redis.clients.jedis.Client; import redis.clients.jedis.Jedis; import redis.clients.jedis.Pipeline; -import redis.clients.jedis.Protocol; import redis.clients.jedis.SortingParams; import redis.clients.jedis.Transaction; import redis.clients.jedis.ZParams; @@ -194,7 +193,7 @@ public class JedisConnection implements RedisConnection { @Override public List closePipeline() { if (pipeline != null) { - List execute = pipeline.execute(); + List execute = pipeline.syncAndReturnAll(); if (execute != null && !execute.isEmpty()) { return execute; } @@ -270,8 +269,7 @@ public class JedisConnection implements RedisConnection { public Long dbSize() { try { if (isQueueing()) { - transaction.dbSize(); - return null; + throw new UnsupportedOperationException(); } if (isPipelined()) { throw new UnsupportedOperationException(); @@ -287,8 +285,7 @@ public class JedisConnection implements RedisConnection { public void flushDb() { try { if (isQueueing()) { - transaction.flushDB(); - return; + throw new UnsupportedOperationException(); } if (isPipelined()) { throw new UnsupportedOperationException(); @@ -303,8 +300,7 @@ public class JedisConnection implements RedisConnection { public void flushAll() { try { if (isQueueing()) { - transaction.flushAll(); - return; + throw new UnsupportedOperationException(); } if (isPipelined()) { throw new UnsupportedOperationException(); @@ -478,8 +474,7 @@ public class JedisConnection implements RedisConnection { public String ping() { try { if (isQueueing()) { - transaction.ping(); - return null; + throw new UnsupportedOperationException(); } if (isPipelined()) { throw new UnsupportedOperationException(); @@ -651,8 +646,7 @@ public class JedisConnection implements RedisConnection { public byte[] randomKey() { try { if (isQueueing()) { - transaction.randomBinaryKey(); - return null; + throw new UnsupportedOperationException(); } if (isPipelined()) { throw new UnsupportedOperationException(); @@ -701,8 +695,7 @@ public class JedisConnection implements RedisConnection { public void select(int dbIndex) { try { if (isQueueing()) { - transaction.select(dbIndex); - return; + throw new UnsupportedOperationException(); } if (isPipelined()) { throw new UnsupportedOperationException(); @@ -1024,8 +1017,6 @@ public class JedisConnection implements RedisConnection { public Boolean getBit(byte[] key, long offset) { try { if (isQueueing()) { - // transaction.getbit(key, (int) offset); - // return null; throw new UnsupportedOperationException(); } if (isPipelined()) { @@ -1041,8 +1032,6 @@ public class JedisConnection implements RedisConnection { public void setBit(byte[] key, long offset, boolean value) { try { if (isQueueing()) { - // transaction.setbit(key, (int) offset, JedisUtils.asBit(value)); - // return; throw new UnsupportedOperationException(); } if (isPipelined()) { @@ -1056,14 +1045,25 @@ public class JedisConnection implements RedisConnection { @Override public void setRange(byte[] key, byte[] value, long start) { - throw new UnsupportedOperationException(); + try { + if (isQueueing()) { + throw new UnsupportedOperationException(); + } + if (isPipelined()) { + throw new UnsupportedOperationException(); + } + jedis.setrange(key, start, value); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } } @Override public Long strLen(byte[] key) { try { if (isQueueing()) { - throw new UnsupportedOperationException(); + transaction.strlen(key); + return null; } if (isPipelined()) { pipeline.strlen(key); @@ -1117,15 +1117,11 @@ public class JedisConnection implements RedisConnection { public List bLPop(int timeout, byte[]... keys) { try { if (isQueueing()) { - throw new UnsupportedOperationException(); + transaction.blpop(JedisUtils.bXPopArgs(timeout, keys)); + return null; } if (isPipelined()) { - final List args = new ArrayList(); - for (final byte[] arg : keys) { - args.add(arg); - } - args.add(Protocol.toByteArray(timeout)); - pipeline.blpop(args.toArray(new byte[args.size()][])); + pipeline.blpop(JedisUtils.bXPopArgs(timeout, keys)); return null; } return jedis.blpop(timeout, keys); @@ -1138,15 +1134,10 @@ public class JedisConnection implements RedisConnection { public List bRPop(int timeout, byte[]... keys) { try { if (isQueueing()) { - throw new UnsupportedOperationException(); + transaction.brpop(JedisUtils.bXPopArgs(timeout, keys)); } if (isPipelined()) { - final List args = new ArrayList(); - for (final byte[] arg : keys) { - args.add(arg); - } - args.add(Protocol.toByteArray(timeout)); - pipeline.brpop(args.toArray(new byte[args.size()][])); + pipeline.brpop(JedisUtils.bXPopArgs(timeout, keys)); return null; } return jedis.brpop(timeout, keys); @@ -1176,9 +1167,8 @@ public class JedisConnection implements RedisConnection { public Long lInsert(byte[] key, Position where, byte[] pivot, byte[] value) { try { if (isQueueing()) { - // transaction.linsert(key, JedisUtils.convertPosition(where), pivot, value); - // return null; - throw new UnsupportedOperationException(); + transaction.linsert(key, JedisUtils.convertPosition(where), pivot, value); + return null; } if (isPipelined()) { pipeline.linsert(key, JedisUtils.convertPosition(where), pivot, value); @@ -1330,7 +1320,8 @@ public class JedisConnection implements RedisConnection { public byte[] bRPopLPush(int timeout, byte[] srcKey, byte[] dstKey) { try { if (isQueueing()) { - throw new UnsupportedOperationException(); + transaction.brpoplpush(srcKey, dstKey, timeout); + return null; } if (isPipelined()) { pipeline.brpoplpush(srcKey, dstKey, timeout); @@ -1346,7 +1337,8 @@ public class JedisConnection implements RedisConnection { public Long lPushX(byte[] key, byte[] value) { try { if (isQueueing()) { - throw new UnsupportedOperationException(); + transaction.lpushx(key, value); + return null; } if (isPipelined()) { pipeline.lpushx(key, value); @@ -1362,7 +1354,8 @@ public class JedisConnection implements RedisConnection { public Long rPushX(byte[] key, byte[] value) { try { if (isQueueing()) { - throw new UnsupportedOperationException(); + transaction.rpushx(key, value); + return null; } if (isPipelined()) { pipeline.rpushx(key, value); @@ -1659,7 +1652,8 @@ public class JedisConnection implements RedisConnection { public Long zCount(byte[] key, double min, double max) { try { if (isQueueing()) { - throw new UnsupportedOperationException(); + transaction.zcount(key, min, max); + return null; } if (isQueueing()) { pipeline.zcount(key, min, max); @@ -1691,11 +1685,13 @@ public class JedisConnection implements RedisConnection { @Override public Long zInterStore(byte[] destKey, Aggregate aggregate, int[] weights, byte[]... sets) { try { - if (isQueueing()) { - throw new UnsupportedOperationException(); - } ZParams zparams = new ZParams().weights(weights).aggregate( redis.clients.jedis.ZParams.Aggregate.valueOf(aggregate.name())); + + if (isQueueing()) { + transaction.zinterstore(destKey, zparams, sets); + return null; + } if (isPipelined()) { pipeline.zinterstore(destKey, zparams, sets); return null; @@ -1710,7 +1706,8 @@ public class JedisConnection implements RedisConnection { public Long zInterStore(byte[] destKey, byte[]... sets) { try { if (isQueueing()) { - throw new UnsupportedOperationException(); + transaction.zinterstore(destKey, sets); + return null; } if (isQueueing()) { pipeline.zinterstore(destKey, sets); @@ -1760,7 +1757,8 @@ public class JedisConnection implements RedisConnection { public Set zRangeByScore(byte[] key, double min, double max) { try { if (isQueueing()) { - throw new UnsupportedOperationException(); + transaction.zrangeByScore(key, min, max); + return null; } if (isPipelined()) { pipeline.zrangeByScore(key, min, max); @@ -1776,7 +1774,8 @@ public class JedisConnection implements RedisConnection { public Set zRangeByScoreWithScore(byte[] key, double min, double max) { try { if (isQueueing()) { - throw new UnsupportedOperationException(); + transaction.zrangeByScoreWithScores(key, min, max); + return null; } if (isPipelined()) { pipeline.zrangeByScoreWithScores(key, min, max); @@ -1792,13 +1791,14 @@ public class JedisConnection implements RedisConnection { public Set zRevRangeWithScore(byte[] key, long start, long end) { try { if (isQueueing()) { - throw new UnsupportedOperationException(); - } - if (isPipelined()) { - pipeline.zrangeByScoreWithScores(key, (int) start, (int) end); + transaction.zrevrangeWithScores(key, (int) start, (int) end); return null; } - return JedisUtils.convertJedisTuple(jedis.zrangeByScoreWithScores(key, (int) start, (int) end)); + if (isPipelined()) { + pipeline.zrevrangeWithScores(key, (int) start, (int) end); + return null; + } + return JedisUtils.convertJedisTuple(jedis.zrevrangeWithScores(key, (int) start, (int) end)); } catch (Exception ex) { throw convertJedisAccessException(ex); } @@ -1808,7 +1808,8 @@ public class JedisConnection implements RedisConnection { public Set zRangeByScore(byte[] key, double min, double max, long offset, long count) { try { if (isQueueing()) { - throw new UnsupportedOperationException(); + transaction.zrangeByScore(key, min, max, (int) offset, (int) count); + return null; } if (isPipelined()) { pipeline.zrangeByScore(key, min, max, (int) offset, (int) count); @@ -1824,7 +1825,8 @@ public class JedisConnection implements RedisConnection { public Set zRangeByScoreWithScore(byte[] key, double min, double max, long offset, long count) { try { if (isQueueing()) { - throw new UnsupportedOperationException(); + transaction.zrangeByScoreWithScores(key, min, max, (int) offset, (int) count); + return null; } if (isPipelined()) { pipeline.zrangeByScoreWithScores(key, min, max, (int) offset, (int) count); @@ -1874,7 +1876,8 @@ public class JedisConnection implements RedisConnection { public Long zRemRange(byte[] key, long start, long end) { try { if (isQueueing()) { - throw new UnsupportedOperationException(); + transaction.zremrangeByRank(key, (int) start, (int) end); + return null; } if (isPipelined()) { pipeline.zremrangeByRank(key, (int) start, (int) end); @@ -1890,7 +1893,8 @@ public class JedisConnection implements RedisConnection { public Long zRemRangeByScore(byte[] key, double min, double max) { try { if (isQueueing()) { - throw new UnsupportedOperationException(); + transaction.zremrangeByScore(key, min, max); + return null; } if (isPipelined()) { pipeline.zremrangeByScore(key, min, max); @@ -1956,11 +1960,13 @@ public class JedisConnection implements RedisConnection { @Override public Long zUnionStore(byte[] destKey, Aggregate aggregate, int[] weights, byte[]... sets) { try { - if (isQueueing()) { - throw new UnsupportedOperationException(); - } ZParams zparams = new ZParams().weights(weights).aggregate( redis.clients.jedis.ZParams.Aggregate.valueOf(aggregate.name())); + + if (isQueueing()) { + transaction.zunionstore(destKey, zparams, sets); + return null; + } if (isPipelined()) { pipeline.zunionstore(destKey, zparams, sets); return null; @@ -1975,7 +1981,8 @@ public class JedisConnection implements RedisConnection { public Long zUnionStore(byte[] destKey, byte[]... sets) { try { if (isQueueing()) { - throw new UnsupportedOperationException(); + transaction.zunionstore(destKey, sets); + return null; } if (isPipelined()) { pipeline.zunionstore(destKey, sets); diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jedis/JedisUtils.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jedis/JedisUtils.java index 06b0011da..f02e30fd8 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jedis/JedisUtils.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jedis/JedisUtils.java @@ -19,8 +19,10 @@ package org.springframework.data.keyvalue.redis.connection.jedis; import java.io.IOException; import java.io.StringReader; import java.net.UnknownHostException; +import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.LinkedHashSet; +import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; @@ -40,6 +42,7 @@ import org.springframework.data.keyvalue.redis.connection.SortParameters.Range; import org.springframework.util.Assert; import redis.clients.jedis.BinaryJedisPubSub; +import redis.clients.jedis.Protocol; import redis.clients.jedis.SortingParams; import redis.clients.jedis.BinaryClient.LIST_POSITION; import redis.clients.jedis.exceptions.JedisConnectionException; @@ -218,4 +221,13 @@ public abstract class JedisUtils { return result; } + + static byte[][] bXPopArgs(int timeout, byte[]... keys) { + final List args = new ArrayList(); + for (final byte[] arg : keys) { + args.add(arg); + } + args.add(Protocol.toByteArray(timeout)); + return args.toArray(new byte[args.size()][]); + } } \ No newline at end of file From 8c3eb982eaf6425e0aa35d2bff8a24e6d1644abe Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Wed, 22 Jun 2011 20:50:50 +0300 Subject: [PATCH 10/13] + wrap up integration (pubsub tests are failing though) --- .../data/keyvalue/redis/connection/jedis/JedisConnection.java | 3 ++- .../redis/connection/AbstractConnectionIntegrationTests.java | 3 --- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jedis/JedisConnection.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jedis/JedisConnection.java index 25c4b9dc6..c6e262ecf 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jedis/JedisConnection.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jedis/JedisConnection.java @@ -2213,7 +2213,8 @@ public class JedisConnection implements RedisConnection { throw new UnsupportedOperationException(); } if (isPipelined()) { - throw new UnsupportedOperationException(); + pipeline.publish(channel, message); + return null; } return jedis.publish(channel, message); } catch (Exception ex) { diff --git a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/connection/AbstractConnectionIntegrationTests.java b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/connection/AbstractConnectionIntegrationTests.java index 875d65b79..b9f311745 100644 --- a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/connection/AbstractConnectionIntegrationTests.java +++ b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/connection/AbstractConnectionIntegrationTests.java @@ -190,7 +190,6 @@ public abstract class AbstractConnectionIntegrationTests { // pub sub test - @Test public void testPubSub() throws Exception { final BlockingDeque queue = new LinkedBlockingDeque(); @@ -244,7 +243,6 @@ public abstract class AbstractConnectionIntegrationTests { assertEquals(3, queue.size()); } - @Test public void testPubSubWithNamedChannels() { final byte[] expectedChannel = "channel1".getBytes(); final byte[] expectedMessage = "msg".getBytes(); @@ -281,7 +279,6 @@ public abstract class AbstractConnectionIntegrationTests { connection.subscribe(listener, expectedChannel); } - @Test public void testPubSubWithPatterns() { final byte[] expectedPattern = "channel*".getBytes(); final byte[] expectedMessage = "msg".getBytes(); From 2d9629140995af1608de552c9d832bc210241a01 Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Wed, 22 Jun 2011 20:58:18 +0300 Subject: [PATCH 11/13] fixed incorrect left/rightPop in RedisTemplate --- .../data/keyvalue/redis/core/DefaultListOperations.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultListOperations.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultListOperations.java index b6c67936f..2349f58ec 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultListOperations.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultListOperations.java @@ -20,6 +20,7 @@ import java.util.concurrent.TimeUnit; import org.springframework.data.keyvalue.redis.connection.RedisConnection; import org.springframework.data.keyvalue.redis.connection.RedisListCommands.Position; +import org.springframework.util.CollectionUtils; /** * Default implementation of {@link ListOperations}. @@ -59,7 +60,8 @@ class DefaultListOperations extends AbstractOperations implements Li return execute(new ValueDeserializingRedisCallback(key) { @Override protected byte[] inRedis(byte[] rawKey, RedisConnection connection) { - return connection.bLPop(tm, rawKey).get(0); + List lPop = connection.bLPop(tm, rawKey); + return (CollectionUtils.isEmpty(lPop) ? null : lPop.get(1)); } }, true); } @@ -153,7 +155,8 @@ class DefaultListOperations extends AbstractOperations implements Li return execute(new ValueDeserializingRedisCallback(key) { @Override protected byte[] inRedis(byte[] rawKey, RedisConnection connection) { - return connection.bRPop(tm, rawKey).get(0); + List bRPop = connection.bRPop(tm, rawKey); + return (CollectionUtils.isEmpty(bRPop) ? null : bRPop.get(1)); } }, true); } From 96d7902c69c1a247db5e3fc641bda45f0590e5a6 Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Fri, 24 Jun 2011 15:01:08 +0300 Subject: [PATCH 12/13] DATAKV-72 + add missing rangeWithScores and reverserRangeWithScores ops for ZSets --- .../DefaultStringRedisConnection.java | 48 ++++-- .../redis/connection/RedisZSetCommands.java | 22 ++- .../connection/StringRedisConnection.java | 8 +- .../connection/jedis/JedisConnection.java | 79 ++++++++-- .../connection/jredis/JredisConnection.java | 29 +++- .../redis/connection/rjc/RjcConnection.java | 148 +++++++++++++----- .../redis/core/AbstractOperations.java | 12 ++ .../redis/core/BoundZSetOperations.java | 12 ++ .../core/DefaultBoundZSetOperations.java | 26 +++ .../redis/core/DefaultTypedTuple.java | 50 ++++++ .../redis/core/DefaultZSetOperations.java | 104 ++++++++++-- .../keyvalue/redis/core/ZSetOperations.java | 23 ++- .../support/collections/CollectionUtils.java | 1 + .../support/collections/DefaultRedisZSet.java | 26 +++ .../RedisCollectionFactoryBean.java | 1 + .../redis/support/collections/RedisZSet.java | 12 ++ 16 files changed, 504 insertions(+), 97 deletions(-) create mode 100644 spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultTypedTuple.java diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/DefaultStringRedisConnection.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/DefaultStringRedisConnection.java index 04484b29f..61b973ed3 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/DefaultStringRedisConnection.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/DefaultStringRedisConnection.java @@ -516,16 +516,32 @@ public class DefaultStringRedisConnection implements StringRedisConnection { return delegate.zRangeByScore(key, min, max); } - public Set zRangeByScoreWithScore(byte[] key, double min, double max, long offset, long count) { - return delegate.zRangeByScoreWithScore(key, min, max, offset, count); + public Set zRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count) { + return delegate.zRangeByScoreWithScores(key, min, max, offset, count); } - public Set zRangeByScoreWithScore(byte[] key, double min, double max) { - return delegate.zRangeByScoreWithScore(key, min, max); + public Set zRangeByScoreWithScores(byte[] key, double min, double max) { + return delegate.zRangeByScoreWithScores(key, min, max); } - public Set zRangeWithScore(byte[] key, long start, long end) { - return delegate.zRangeWithScore(key, start, end); + public Set zRangeWithScores(byte[] key, long start, long end) { + return delegate.zRangeWithScores(key, start, end); + } + + public Set zRevRangeByScore(byte[] key, double min, double max, long offset, long count) { + return delegate.zRevRangeByScore(key, min, max, offset, count); + } + + public Set zRevRangeByScore(byte[] key, double min, double max) { + return delegate.zRevRangeByScore(key, min, max); + } + + public Set zRevRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count) { + return delegate.zRevRangeByScoreWithScores(key, min, max, offset, count); + } + + public Set zRevRangeByScoreWithScores(byte[] key, double min, double max) { + return delegate.zRevRangeByScoreWithScores(key, min, max); } public Long zRank(byte[] key, byte[] value) { @@ -548,8 +564,8 @@ public class DefaultStringRedisConnection implements StringRedisConnection { return delegate.zRevRange(key, start, end); } - public Set zRevRangeWithScore(byte[] key, long start, long end) { - return delegate.zRevRangeWithScore(key, start, end); + public Set zRevRangeWithScores(byte[] key, long start, long end) { + return delegate.zRevRangeWithScores(key, start, end); } public Long zRevRank(byte[] key, byte[] value) { @@ -1058,18 +1074,18 @@ public class DefaultStringRedisConnection implements StringRedisConnection { } @Override - public Set zRangeByScoreWithScore(String key, double min, double max, long offset, long count) { - return deserializeTuple(delegate.zRangeByScoreWithScore(serialize(key), min, max, offset, count)); + public Set zRangeByScoreWithScores(String key, double min, double max, long offset, long count) { + return deserializeTuple(delegate.zRangeByScoreWithScores(serialize(key), min, max, offset, count)); } @Override - public Set zRangeByScoreWithScore(String key, double min, double max) { - return deserializeTuple(delegate.zRangeByScoreWithScore(serialize(key), min, max)); + public Set zRangeByScoreWithScores(String key, double min, double max) { + return deserializeTuple(delegate.zRangeByScoreWithScores(serialize(key), min, max)); } @Override - public Set zRangeWithScore(String key, long start, long end) { - return deserializeTuple(delegate.zRangeWithScore(serialize(key), start, end)); + public Set zRangeWithScores(String key, long start, long end) { + return deserializeTuple(delegate.zRangeWithScores(serialize(key), start, end)); } @Override @@ -1098,8 +1114,8 @@ public class DefaultStringRedisConnection implements StringRedisConnection { } @Override - public Set zRevRangeWithScore(String key, long start, long end) { - return deserializeTuple(delegate.zRevRangeWithScore(serialize(key), start, end)); + public Set zRevRangeWithScores(String key, long start, long end) { + return deserializeTuple(delegate.zRevRangeWithScores(serialize(key), start, end)); } @Override diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/RedisZSetCommands.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/RedisZSetCommands.java index eacc7de72..ff6073b8c 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/RedisZSetCommands.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/RedisZSetCommands.java @@ -54,19 +54,27 @@ public interface RedisZSetCommands { Set zRange(byte[] key, long begin, long end); - Set zRangeWithScore(byte[] key, long begin, long end); - - Set zRevRange(byte[] key, long begin, long end); - - Set zRevRangeWithScore(byte[] key, long begin, long end); + Set zRangeWithScores(byte[] key, long begin, long end); Set zRangeByScore(byte[] key, double min, double max); - Set zRangeByScoreWithScore(byte[] key, double min, double max); + Set zRangeByScoreWithScores(byte[] key, double min, double max); Set zRangeByScore(byte[] key, double min, double max, long offset, long count); - Set zRangeByScoreWithScore(byte[] key, double min, double max, long offset, long count); + Set zRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count); + + Set zRevRange(byte[] key, long begin, long end); + + Set zRevRangeWithScores(byte[] key, long begin, long end); + + Set zRevRangeByScore(byte[] key, double min, double max); + + Set zRevRangeByScoreWithScores(byte[] key, double min, double max); + + Set zRevRangeByScore(byte[] key, double min, double max, long offset, long count); + + Set zRevRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count); Long zCount(byte[] key, double min, double max); diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/StringRedisConnection.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/StringRedisConnection.java index 28886d595..fc7c170aa 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/StringRedisConnection.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/StringRedisConnection.java @@ -181,19 +181,19 @@ public interface StringRedisConnection extends RedisConnection { Set zRange(String key, long start, long end); - Set zRangeWithScore(String key, long start, long end); + Set zRangeWithScores(String key, long start, long end); Set zRevRange(String key, long start, long end); - Set zRevRangeWithScore(String key, long start, long end); + Set zRevRangeWithScores(String key, long start, long end); Set zRangeByScore(String key, double min, double max); - Set zRangeByScoreWithScore(String key, double min, double max); + Set zRangeByScoreWithScores(String key, double min, double max); Set zRangeByScore(String key, double min, double max, long offset, long count); - Set zRangeByScoreWithScore(String key, double min, double max, long offset, long count); + Set zRangeByScoreWithScores(String key, double min, double max, long offset, long count); Long zCount(String key, double min, double max); diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jedis/JedisConnection.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jedis/JedisConnection.java index 0d751765a..b55ea93ba 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jedis/JedisConnection.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jedis/JedisConnection.java @@ -1740,7 +1740,7 @@ public class JedisConnection implements RedisConnection { } @Override - public Set zRangeWithScore(byte[] key, long start, long end) { + public Set zRangeWithScores(byte[] key, long start, long end) { try { if (isQueueing()) { transaction.zrangeWithScores(key, (int) start, (int) end); @@ -1773,7 +1773,7 @@ public class JedisConnection implements RedisConnection { } @Override - public Set zRangeByScoreWithScore(byte[] key, double min, double max) { + public Set zRangeByScoreWithScores(byte[] key, double min, double max) { try { if (isQueueing()) { throw new UnsupportedOperationException(); @@ -1789,16 +1789,17 @@ public class JedisConnection implements RedisConnection { } @Override - public Set zRevRangeWithScore(byte[] key, long start, long end) { + public Set zRevRangeWithScores(byte[] key, long start, long end) { try { if (isQueueing()) { - throw new UnsupportedOperationException(); - } - if (isPipelined()) { - pipeline.zrangeByScoreWithScores(key, (int) start, (int) end); + transaction.zrevrangeWithScores(key, (int) start, (int) end); return null; } - return JedisUtils.convertJedisTuple(jedis.zrangeByScoreWithScores(key, (int) start, (int) end)); + if (isPipelined()) { + pipeline.zrevrangeWithScores(key, (int) start, (int) end); + return null; + } + return JedisUtils.convertJedisTuple(jedis.zrevrangeWithScores(key, (int) start, (int) end)); } catch (Exception ex) { throw convertJedisAccessException(ex); } @@ -1821,7 +1822,7 @@ public class JedisConnection implements RedisConnection { } @Override - public Set zRangeByScoreWithScore(byte[] key, double min, double max, long offset, long count) { + public Set zRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count) { try { if (isQueueing()) { throw new UnsupportedOperationException(); @@ -1836,6 +1837,66 @@ public class JedisConnection implements RedisConnection { } } + @Override + public Set zRevRangeByScore(byte[] key, double min, double max, long offset, long count) { + try { + if (isQueueing()) { + throw new UnsupportedOperationException(); + } + if (isPipelined()) { + throw new UnsupportedOperationException(); + } + throw new UnsupportedOperationException(); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + @Override + public Set zRevRangeByScore(byte[] key, double min, double max) { + try { + if (isQueueing()) { + throw new UnsupportedOperationException(); + } + if (isPipelined()) { + throw new UnsupportedOperationException(); + } + throw new UnsupportedOperationException(); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + @Override + public Set zRevRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count) { + try { + if (isQueueing()) { + throw new UnsupportedOperationException(); + } + if (isPipelined()) { + throw new UnsupportedOperationException(); + } + throw new UnsupportedOperationException(); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + + @Override + public Set zRevRangeByScoreWithScores(byte[] key, double min, double max) { + try { + if (isQueueing()) { + throw new UnsupportedOperationException(); + } + if (isPipelined()) { + throw new UnsupportedOperationException(); + } + throw new UnsupportedOperationException(); + } catch (Exception ex) { + throw convertJedisAccessException(ex); + } + } + @Override public Long zRank(byte[] key, byte[] value) { try { diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jredis/JredisConnection.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jredis/JredisConnection.java index ada3441e1..00433eee2 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jredis/JredisConnection.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/jredis/JredisConnection.java @@ -886,9 +886,8 @@ public class JredisConnection implements RedisConnection { } @Override - public Set zRangeWithScore(byte[] key, long start, long end) { + public Set zRangeWithScores(byte[] key, long start, long end) { throw new UnsupportedOperationException(); - } @Override @@ -901,7 +900,7 @@ public class JredisConnection implements RedisConnection { } @Override - public Set zRangeByScoreWithScore(byte[] key, double min, double max) { + public Set zRangeByScoreWithScores(byte[] key, double min, double max) { throw new UnsupportedOperationException(); } @@ -911,7 +910,27 @@ public class JredisConnection implements RedisConnection { } @Override - public Set zRangeByScoreWithScore(byte[] key, double min, double max, long offset, long count) { + public Set zRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count) { + throw new UnsupportedOperationException(); + } + + @Override + public Set zRevRangeByScore(byte[] key, double min, double max, long offset, long count) { + throw new UnsupportedOperationException(); + } + + @Override + public Set zRevRangeByScore(byte[] key, double min, double max) { + throw new UnsupportedOperationException(); + } + + @Override + public Set zRevRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count) { + throw new UnsupportedOperationException(); + } + + @Override + public Set zRevRangeByScoreWithScores(byte[] key, double min, double max) { throw new UnsupportedOperationException(); } @@ -961,7 +980,7 @@ public class JredisConnection implements RedisConnection { } @Override - public Set zRevRangeWithScore(byte[] key, long start, long end) { + public Set zRevRangeWithScores(byte[] key, long start, long end) { throw new UnsupportedOperationException(); } diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/rjc/RjcConnection.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/rjc/RjcConnection.java index 5b9c739a1..1176fc57d 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/rjc/RjcConnection.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/connection/rjc/RjcConnection.java @@ -1547,7 +1547,7 @@ public class RjcConnection implements RedisConnection { } @Override - public Set zRangeWithScore(byte[] key, long start, long end) { + public Set zRangeWithScores(byte[] key, long start, long end) { String stringKey = RjcUtils.decode(key); try { @@ -1578,41 +1578,6 @@ public class RjcConnection implements RedisConnection { } } - @Override - public Set zRangeByScoreWithScore(byte[] key, double min, double max) { - String stringKey = RjcUtils.decode(key); - String minString = Double.toString(min); - String maxString = Double.toString(max); - - try { - if (isPipelined()) { - pipeline.zrangeByScoreWithScores(stringKey, minString, maxString); - return null; - } - return RjcUtils.convertElementScore(session.zrangeByScoreWithScores(stringKey, minString, maxString)); - } catch (Exception ex) { - throw convertRjcAccessException(ex); - } - } - - @Override - public Set zRevRangeWithScore(byte[] key, long start, long end) { - String stringKey = RjcUtils.decode(key); - String minString = Long.toString(start); - String maxString = Long.toString(end); - - try { - - if (isPipelined()) { - pipeline.zrangeByScoreWithScores(stringKey, minString, maxString); - return null; - } - return RjcUtils.convertElementScore(session.zrangeByScoreWithScores(stringKey, minString, maxString)); - } catch (Exception ex) { - throw convertRjcAccessException(ex); - } - } - @Override public Set zRangeByScore(byte[] key, double min, double max, long offset, long count) { String stringKey = RjcUtils.decode(key); @@ -1631,8 +1596,79 @@ public class RjcConnection implements RedisConnection { } } + @Override - public Set zRangeByScoreWithScore(byte[] key, double min, double max, long offset, long count) { + public Set zRevRangeByScore(byte[] key, double min, double max, long offset, long count) { + String stringKey = RjcUtils.decode(key); + String minString = Double.toString(min); + String maxString = Double.toString(max); + + try { + if (isPipelined()) { + pipeline.zrevrangeByScore(stringKey, minString, maxString, (int) offset, (int) count); + return null; + } + return RjcUtils.convertToSet(session.zrevrangeByScore(stringKey, minString, maxString, (int) offset, + (int) count)); + } catch (Exception ex) { + throw convertRjcAccessException(ex); + } + } + + @Override + public Set zRevRangeByScore(byte[] key, double min, double max) { + String stringKey = RjcUtils.decode(key); + String minString = Double.toString(min); + String maxString = Double.toString(max); + + try { + if (isPipelined()) { + pipeline.zrevrangeByScore(stringKey, minString, maxString); + return null; + } + return RjcUtils.convertToSet(session.zrevrangeByScore(stringKey, minString, maxString)); + } catch (Exception ex) { + throw convertRjcAccessException(ex); + } + } + + @Override + public Set zRangeByScoreWithScores(byte[] key, double min, double max) { + String stringKey = RjcUtils.decode(key); + String minString = Double.toString(min); + String maxString = Double.toString(max); + + try { + if (isPipelined()) { + pipeline.zrangeByScoreWithScores(stringKey, minString, maxString); + return null; + } + return RjcUtils.convertElementScore(session.zrangeByScoreWithScores(stringKey, minString, maxString)); + } catch (Exception ex) { + throw convertRjcAccessException(ex); + } + } + + @Override + public Set zRevRangeWithScores(byte[] key, long start, long end) { + String stringKey = RjcUtils.decode(key); + String minString = Long.toString(start); + String maxString = Long.toString(end); + + try { + + if (isPipelined()) { + pipeline.zrevrangeByScoreWithScores(stringKey, minString, maxString); + return null; + } + return RjcUtils.convertElementScore(session.zrevrangeByScoreWithScores(stringKey, minString, maxString)); + } catch (Exception ex) { + throw convertRjcAccessException(ex); + } + } + + @Override + public Set zRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count) { String stringKey = RjcUtils.decode(key); String minString = Double.toString(min); String maxString = Double.toString(max); @@ -1649,6 +1685,44 @@ public class RjcConnection implements RedisConnection { } } + + @Override + public Set zRevRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count) { + String stringKey = RjcUtils.decode(key); + String minString = Double.toString(min); + String maxString = Double.toString(max); + + try { + + if (isPipelined()) { + pipeline.zrevrangeByScoreWithScores(stringKey, minString, maxString, (int) offset, (int) count); + return null; + } + return RjcUtils.convertElementScore(session.zrevrangeByScoreWithScores(stringKey, minString, maxString, + (int) offset, (int) count)); + } catch (Exception ex) { + throw convertRjcAccessException(ex); + } + } + + @Override + public Set zRevRangeByScoreWithScores(byte[] key, double min, double max) { + String stringKey = RjcUtils.decode(key); + String minString = Double.toString(min); + String maxString = Double.toString(max); + + try { + + if (isPipelined()) { + pipeline.zrevrangeByScoreWithScores(stringKey, minString, maxString); + return null; + } + return RjcUtils.convertElementScore(session.zrevrangeByScoreWithScores(stringKey, minString, maxString)); + } catch (Exception ex) { + throw convertRjcAccessException(ex); + } + } + @Override public Long zRank(byte[] key, byte[] value) { String stringKey = RjcUtils.decode(key); diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/AbstractOperations.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/AbstractOperations.java index ccaeedfe4..1b15b4747 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/AbstractOperations.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/AbstractOperations.java @@ -17,11 +17,14 @@ package org.springframework.data.keyvalue.redis.core; import java.util.Collection; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.springframework.data.keyvalue.redis.connection.RedisConnection; +import org.springframework.data.keyvalue.redis.connection.RedisZSetCommands.Tuple; +import org.springframework.data.keyvalue.redis.core.ZSetOperations.TypedTuple; import org.springframework.data.keyvalue.redis.serializer.RedisSerializer; import org.springframework.data.keyvalue.redis.serializer.SerializationUtils; import org.springframework.util.Assert; @@ -136,6 +139,15 @@ abstract class AbstractOperations { return SerializationUtils.deserialize(rawValues, valueSerializer); } + @SuppressWarnings("unchecked") + Set> deserializeTupleValues(Set rawValues) { + Set> set = new LinkedHashSet>(rawValues.size()); + for (Tuple rawValue : rawValues) { + set.add(new DefaultTypedTuple(valueSerializer.deserialize(rawValue.getValue()), rawValue.getScore())); + } + return set; + } + @SuppressWarnings("unchecked") List deserializeValues(List rawValues) { return SerializationUtils.deserialize(rawValues, valueSerializer); diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BoundZSetOperations.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BoundZSetOperations.java index 2ba5783d4..162e9dd51 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BoundZSetOperations.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BoundZSetOperations.java @@ -19,6 +19,8 @@ package org.springframework.data.keyvalue.redis.core; import java.util.Collection; import java.util.Set; +import org.springframework.data.keyvalue.redis.core.ZSetOperations.TypedTuple; + /** * ZSet (or SortedSet) operations bound to a certain key. @@ -39,6 +41,16 @@ public interface BoundZSetOperations extends BoundKeyOperations { Set reverseRange(long start, long end); + Set reverseRangeByScore(double min, double max); + + Set> rangeWithScores(long start, long end); + + Set> rangeByScoreWithScores(double min, double max); + + Set> reverseRangeWithScores(long start, long end); + + Set> reverseRangeByScoreWithScores(double min, double max); + void removeRange(long start, long end); void removeRangeByScore(double min, double max); diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundZSetOperations.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundZSetOperations.java index 71590d863..60f847bc5 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundZSetOperations.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundZSetOperations.java @@ -20,6 +20,7 @@ import java.util.Collection; import java.util.Set; import org.springframework.data.keyvalue.redis.connection.DataType; +import org.springframework.data.keyvalue.redis.core.ZSetOperations.TypedTuple; /** * Default implementation for {@link BoundZSetOperations}. @@ -76,6 +77,31 @@ class DefaultBoundZSetOperations extends DefaultBoundKeyOperations impl return ops.rangeByScore(getKey(), min, max); } + @Override + public Set> rangeByScoreWithScores(double min, double max) { + return ops.rangeByScoreWithScores(getKey(), min, max); + } + + @Override + public Set> rangeWithScores(long start, long end) { + return ops.rangeWithScores(getKey(), start, end); + } + + @Override + public Set reverseRangeByScore(double min, double max) { + return ops.reverseRangeByScore(getKey(), min, max); + } + + @Override + public Set> reverseRangeByScoreWithScores(double min, double max) { + return ops.reverseRangeByScoreWithScores(getKey(), min, max); + } + + @Override + public Set> reverseRangeWithScores(long start, long end) { + return ops.reverseRangeWithScores(getKey(), start, end); + } + @Override public Long rank(Object o) { return ops.rank(getKey(), o); diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultTypedTuple.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultTypedTuple.java new file mode 100644 index 000000000..fc23e6d79 --- /dev/null +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultTypedTuple.java @@ -0,0 +1,50 @@ +/* + * Copyright 2011 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 + * + * http://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 org.springframework.data.keyvalue.redis.core; + +import org.springframework.data.keyvalue.redis.core.ZSetOperations.TypedTuple; + +/** + * Default implementation of TypedTuple. + * + * @author Costin Leau + */ +class DefaultTypedTuple implements TypedTuple { + + private final Double score; + private final V value; + + /** + * Constructs a new DefaultTypedTuple instance. + * + * @param value + * @param score + */ + public DefaultTypedTuple(V value, Double score) { + this.score = score; + this.value = value; + } + + @Override + public Double getScore() { + return score; + } + + @Override + public V getValue() { + return value; + } +} diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultZSetOperations.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultZSetOperations.java index 154163fe7..c0198d010 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultZSetOperations.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultZSetOperations.java @@ -20,6 +20,7 @@ import java.util.Collections; import java.util.Set; import org.springframework.data.keyvalue.redis.connection.RedisConnection; +import org.springframework.data.keyvalue.redis.connection.RedisZSetCommands.Tuple; /** * Default implementation of {@link ZSetOperations}. @@ -76,7 +77,6 @@ class DefaultZSetOperations extends AbstractOperations implements ZS }, true); } - @SuppressWarnings("unchecked") @Override public Set range(K key, final long start, final long end) { final byte[] rawKey = rawKey(key); @@ -91,7 +91,48 @@ class DefaultZSetOperations extends AbstractOperations implements ZS return deserializeValues(rawValues); } - @SuppressWarnings("unchecked") + @Override + public Set reverseRange(K key, final long start, final long end) { + final byte[] rawKey = rawKey(key); + + Set rawValues = execute(new RedisCallback>() { + @Override + public Set doInRedis(RedisConnection connection) { + return connection.zRevRange(rawKey, start, end); + } + }, true); + + return deserializeValues(rawValues); + } + + @Override + public Set> rangeWithScores(K key, final long start, final long end) { + final byte[] rawKey = rawKey(key); + + Set rawValues = execute(new RedisCallback>() { + @Override + public Set doInRedis(RedisConnection connection) { + return connection.zRangeWithScores(rawKey, start, end); + } + }, true); + + return deserializeTupleValues(rawValues); + } + + @Override + public Set> reverseRangeWithScores(K key, final long start, final long end) { + final byte[] rawKey = rawKey(key); + + Set rawValues = execute(new RedisCallback>() { + @Override + public Set doInRedis(RedisConnection connection) { + return connection.zRevRangeWithScores(rawKey, start, end); + } + }, true); + + return deserializeTupleValues(rawValues); + } + @Override public Set rangeByScore(K key, final double min, final double max) { final byte[] rawKey = rawKey(key); @@ -106,6 +147,50 @@ class DefaultZSetOperations extends AbstractOperations implements ZS return deserializeValues(rawValues); } + + @Override + public Set reverseRangeByScore(K key, final double min, final double max) { + final byte[] rawKey = rawKey(key); + + Set rawValues = execute(new RedisCallback>() { + @Override + public Set doInRedis(RedisConnection connection) { + return connection.zRevRangeByScore(rawKey, min, max); + } + }, true); + + return deserializeValues(rawValues); + } + + @Override + public Set> rangeByScoreWithScores(K key, final double min, final double max) { + final byte[] rawKey = rawKey(key); + + Set rawValues = execute(new RedisCallback>() { + @Override + public Set doInRedis(RedisConnection connection) { + return connection.zRangeByScoreWithScores(rawKey, min, max); + } + }, true); + + return deserializeTupleValues(rawValues); + } + + @Override + public Set> reverseRangeByScoreWithScores(K key, final double min, final double max) { + final byte[] rawKey = rawKey(key); + + Set rawValues = execute(new RedisCallback>() { + @Override + public Set doInRedis(RedisConnection connection) { + return connection.zRevRangeByScoreWithScores(rawKey, min, max); + + } + }, true); + + return deserializeTupleValues(rawValues); + } + @Override public Long rank(K key, Object o) { final byte[] rawKey = rawKey(key); @@ -171,21 +256,6 @@ class DefaultZSetOperations extends AbstractOperations implements ZS }, true); } - @SuppressWarnings("unchecked") - @Override - public Set reverseRange(K key, final long start, final long end) { - final byte[] rawKey = rawKey(key); - - Set rawValues = execute(new RedisCallback>() { - @Override - public Set doInRedis(RedisConnection connection) { - return connection.zRevRange(rawKey, start, end); - } - }, true); - - return deserializeValues(rawValues); - } - @Override public Double score(K key, Object o) { final byte[] rawKey = rawKey(key); diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/ZSetOperations.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/ZSetOperations.java index 221138af9..87bf0784c 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/ZSetOperations.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/ZSetOperations.java @@ -26,6 +26,15 @@ import java.util.Set; */ public interface ZSetOperations { + /** + * Typed ZSet tuple. + */ + public interface TypedTuple { + V getValue(); + + Double getScore(); + } + void intersectAndStore(K key, K otherKey, K destKey); void intersectAndStore(K key, Collection otherKeys, K destKey); @@ -36,9 +45,19 @@ public interface ZSetOperations { Set range(K key, long start, long end); + Set reverseRange(K key, long start, long end); + + Set> rangeWithScores(K key, long start, long end); + + Set> reverseRangeWithScores(K key, long start, long end); + Set rangeByScore(K key, double min, double max); - Set reverseRange(K key, long start, long end); + Set reverseRangeByScore(K key, double min, double max); + + Set> rangeByScoreWithScores(K key, double min, double max); + + Set> reverseRangeByScoreWithScores(K key, double min, double max); Boolean add(K key, V value, double score); @@ -61,4 +80,4 @@ public interface ZSetOperations { Long size(K key); RedisOperations getOperations(); -} +} \ No newline at end of file diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/CollectionUtils.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/CollectionUtils.java index e98c8287a..1e4ee5fea 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/CollectionUtils.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/CollectionUtils.java @@ -76,6 +76,7 @@ abstract class CollectionUtils { static Boolean renameIfAbsent(final K key, final K newKey, RedisOperations operations) { return operations.execute(new SessionCallback() { + @SuppressWarnings("unchecked") @Override public Boolean execute(RedisOperations operations) throws DataAccessException { List exec = null; diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/DefaultRedisZSet.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/DefaultRedisZSet.java index 4794aae99..3da68a34d 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/DefaultRedisZSet.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/DefaultRedisZSet.java @@ -23,6 +23,7 @@ import java.util.Set; import org.springframework.data.keyvalue.redis.connection.DataType; import org.springframework.data.keyvalue.redis.core.BoundZSetOperations; import org.springframework.data.keyvalue.redis.core.RedisOperations; +import org.springframework.data.keyvalue.redis.core.ZSetOperations.TypedTuple; /** * Default implementation for {@link RedisZSet}. @@ -118,6 +119,31 @@ public class DefaultRedisZSet extends AbstractRedisCollection implements R return boundZSetOps.rangeByScore(min, max); } + @Override + public Set reverseRangeByScore(double min, double max) { + return boundZSetOps.reverseRangeByScore(min, max); + } + + @Override + public Set> rangeByScoreWithScores(double min, double max) { + return boundZSetOps.rangeByScoreWithScores(min, max); + } + + @Override + public Set> rangeWithScores(long start, long end) { + return boundZSetOps.rangeWithScores(start, end); + } + + @Override + public Set> reverseRangeByScoreWithScores(double min, double max) { + return boundZSetOps.reverseRangeByScoreWithScores(min, max); + } + + @Override + public Set> reverseRangeWithScores(long start, long end) { + return boundZSetOps.reverseRangeWithScores(start, end); + } + @Override public RedisZSet remove(long start, long end) { boundZSetOps.removeRange(start, end); diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/RedisCollectionFactoryBean.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/RedisCollectionFactoryBean.java index 0f0fa8249..2ea8086f2 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/RedisCollectionFactoryBean.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/RedisCollectionFactoryBean.java @@ -98,6 +98,7 @@ public class RedisCollectionFactoryBean implements InitializingBean, BeanNameAwa } } + @SuppressWarnings("unchecked") private RedisStore createStore(DataType dt) { switch (dt) { case LIST: diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/RedisZSet.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/RedisZSet.java index 0d6c24221..437fa5f09 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/RedisZSet.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/collections/RedisZSet.java @@ -21,6 +21,8 @@ import java.util.NoSuchElementException; import java.util.Set; import java.util.SortedSet; +import org.springframework.data.keyvalue.redis.core.ZSetOperations.TypedTuple; + /** * Redis ZSet (or sorted set (by weight)). Acts as a {@link SortedSet} based on the given priorities or weights associated with each item. *

@@ -44,6 +46,16 @@ public interface RedisZSet extends RedisCollection, Set { Set rangeByScore(double min, double max); + Set reverseRangeByScore(double min, double max); + + Set> rangeWithScores(long start, long end); + + Set> reverseRangeWithScores(long start, long end); + + Set> rangeByScoreWithScores(double min, double max); + + Set> reverseRangeByScoreWithScores(double min, double max); + RedisZSet remove(long start, long end); RedisZSet removeByScore(double min, double max); From 7c0295aacc09289b466e7a3cf8eeccf02cd5ecc5 Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Fri, 1 Jul 2011 15:09:26 +0300 Subject: [PATCH 13/13] DATAKV-74 --- .../connection/AbstractConnectionIntegrationTests.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/connection/AbstractConnectionIntegrationTests.java b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/connection/AbstractConnectionIntegrationTests.java index b9f311745..79266a5ec 100644 --- a/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/connection/AbstractConnectionIntegrationTests.java +++ b/spring-data-redis/src/test/java/org/springframework/data/keyvalue/redis/connection/AbstractConnectionIntegrationTests.java @@ -189,7 +189,7 @@ public abstract class AbstractConnectionIntegrationTests { } // pub sub test - + @Test public void testPubSub() throws Exception { final BlockingDeque queue = new LinkedBlockingDeque(); @@ -243,6 +243,7 @@ public abstract class AbstractConnectionIntegrationTests { assertEquals(3, queue.size()); } + @Test public void testPubSubWithNamedChannels() { final byte[] expectedChannel = "channel1".getBytes(); final byte[] expectedMessage = "msg".getBytes(); @@ -261,7 +262,7 @@ public abstract class AbstractConnectionIntegrationTests { public void run() { // sleep 1 second to let the registration happen try { - Thread.currentThread().sleep(1000); + Thread.currentThread().sleep(2000); } catch (InterruptedException ex) { throw new RuntimeException(ex); } @@ -279,6 +280,7 @@ public abstract class AbstractConnectionIntegrationTests { connection.subscribe(listener, expectedChannel); } + @Test public void testPubSubWithPatterns() { final byte[] expectedPattern = "channel*".getBytes(); final byte[] expectedMessage = "msg".getBytes(); @@ -298,7 +300,7 @@ public abstract class AbstractConnectionIntegrationTests { public void run() { // sleep 1 second to let the registration happen try { - Thread.currentThread().sleep(1000); + Thread.currentThread().sleep(1500); } catch (InterruptedException ex) { throw new RuntimeException(ex); }