Add Redis 2.6 hincrbyfloat to RedisMap and HashOperations

DATAREDIS-181
This commit is contained in:
Jennifer Hickey
2013-06-17 16:26:10 -07:00
parent ced5a755e9
commit 128360d43c
12 changed files with 172 additions and 9 deletions

View File

@@ -33,6 +33,8 @@ public interface BoundHashOperations<H, HK, HV> extends BoundKeyOperations<H> {
Long increment(HK key, long delta);
Double increment(HK key, double delta);
HV get(Object key);
void put(HK key, HV value);

View File

@@ -72,7 +72,10 @@ class DefaultBoundHashOperations<H, HK, HV> extends DefaultBoundKeyOperations<H>
return ops.increment(getKey(), key, delta);
}
public Double increment(HK key, double delta) {
return ops.increment(getKey(), key, delta);
}
public Set<HK> keys() {
return ops.keys(getKey());
}

View File

@@ -79,7 +79,17 @@ class DefaultHashOperations<K, HK, HV> extends AbstractOperations<K, Object> imp
}
public Double increment(K key, HK hashKey, final double delta) {
final byte[] rawKey = rawKey(key);
final byte[] rawHashKey = rawHashKey(hashKey);
return execute(new RedisCallback<Double>() {
public Double doInRedis(RedisConnection connection) {
return connection.hIncrBy(rawKey, rawHashKey, delta);
}
}, true);
}
public Set<HK> keys(K key) {
final byte[] rawKey = rawKey(key);

View File

@@ -37,6 +37,8 @@ public interface HashOperations<H, HK, HV> {
Long increment(H key, HK hashKey, long delta);
Double increment(H key, HK hashKey, double delta);
Set<HK> keys(H key);
Long size(H key);

View File

@@ -89,7 +89,11 @@ public class DefaultRedisMap<K, V> implements RedisMap<K, V> {
public Long increment(K key, long delta) {
return hashOps.increment(key, delta);
}
public Double increment(K key, double delta) {
return hashOps.increment(key, delta);
}
public RedisOperations<String, ?> getOperations() {
return hashOps.getOperations();
}

View File

@@ -26,4 +26,6 @@ import java.util.concurrent.ConcurrentMap;
public interface RedisMap<K, V> extends RedisStore, ConcurrentMap<K, V> {
Long increment(K key, long delta);
Double increment(K key, double delta);
}

View File

@@ -23,7 +23,6 @@ import java.util.Date;
import java.util.Enumeration;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@@ -209,8 +208,11 @@ public class RedisProperties extends Properties implements RedisMap<Object, Obje
public Long increment(Object key, long delta) {
return hashOps.increment((String) key, delta);
}
public Double increment(Object key, double delta) {
return hashOps.increment((String) key, delta);
}
public RedisOperations<String, ?> getOperations() {
return hashOps.getOperations();
}

View File

@@ -51,6 +51,7 @@ import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.annotation.IfProfileValue;
/**
* Integration test for Redis Map.
@@ -194,8 +195,9 @@ public abstract class AbstractRedisMapTests<K, V> {
}
@Test
public void testIncrement() {
assumeTrue(!ConnectionUtils.isJredis(template.getConnectionFactory()));
public void testIncrementNotNumber() {
assumeTrue(!ConnectionUtils.isJredis(template.getConnectionFactory()) &&
!(valueFactory instanceof LongObjectFactory));
K k1 = getKey();
V v1 = getValue();
@@ -210,6 +212,25 @@ public abstract class AbstractRedisMapTests<K, V> {
}
}
@Test
public void testIncrement() {
assumeTrue(valueFactory instanceof LongObjectFactory);
K k1 = getKey();
V v1 = getValue();
map.put(k1, v1);
assertEquals(Long.valueOf(Long.valueOf((String)v1) + 10), map.increment(k1, 10));
}
@IfProfileValue(name = "redisVersion", value = "2.6")
@Test
public void testIncrementDouble() {
assumeTrue(valueFactory instanceof DoubleObjectFactory);
K k1 = getKey();
V v1 = getValue();
map.put(k1, v1);
assertEquals(Double.valueOf(Double.valueOf((String)v1) + 3.4), map.increment(k1, 3.4));
}
@Test
public void testIsEmpty() {
map.clear();

View File

@@ -0,0 +1,34 @@
/*
* Copyright 2013 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.redis.support.collections;
import java.util.Random;
/**
*
* Implementation of {@link ObjectFactory that returns random Doubles as Strings
* @author Jennifer Hickey
*
*/
public class DoubleObjectFactory implements ObjectFactory<String> {
private Random random = new Random(System.currentTimeMillis());
public String instance() {
return String.valueOf(random.nextDouble());
}
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright 2013 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.redis.support.collections;
import java.util.Random;
/**
*
* Implementation of {@link ObjectFactory that returns random Longs as Strings
* @author Jennifer Hickey
*
*/
public class LongObjectFactory implements ObjectFactory<String> {
private Random random = new Random(System.currentTimeMillis());
public String instance() {
return String.valueOf(random.nextLong());
}
}

View File

@@ -27,8 +27,10 @@ import org.springframework.data.redis.connection.jredis.JredisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.srp.SrpConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.JacksonJsonRedisSerializer;
import org.springframework.data.redis.serializer.OxmSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.oxm.xstream.XStreamMarshaller;
/**
@@ -65,6 +67,8 @@ public class RedisMapTests extends AbstractRedisMapTests<Object, Object> {
// create Jedis Factory
ObjectFactory<String> stringFactory = new StringObjectFactory();
ObjectFactory<Person> personFactory = new PersonObjectFactory();
ObjectFactory<String> doubleFactory = new DoubleObjectFactory();
ObjectFactory<String> longFactory = new LongObjectFactory();
JedisConnectionFactory jedisConnFactory = new JedisConnectionFactory();
jedisConnFactory.setUsePool(true);
@@ -131,6 +135,10 @@ public class RedisMapTests extends AbstractRedisMapTests<Object, Object> {
jsonPersonTemplateLettuce.setHashValueSerializer(jsonStringSerializer);
jsonPersonTemplateLettuce.afterPropertiesSet();
RedisTemplate<String, String> stringTemplateLtc = new StringRedisTemplate();
stringTemplateLtc.setConnectionFactory(lettuceConnFactory);
stringTemplateLtc.afterPropertiesSet();
// SRP
SrpConnectionFactory srpConnFactory = new SrpConnectionFactory();
srpConnFactory.setPort(SettingsUtils.getPort());
@@ -153,6 +161,10 @@ public class RedisMapTests extends AbstractRedisMapTests<Object, Object> {
jsonPersonTemplateSrp.setHashValueSerializer(jsonStringSerializer);
jsonPersonTemplateSrp.afterPropertiesSet();
RedisTemplate<String, String> stringTemplateSrp = new StringRedisTemplate();
stringTemplateSrp.setConnectionFactory(srpConnFactory);
stringTemplateSrp.afterPropertiesSet();
return Arrays.asList(new Object[][] {
{ stringFactory, stringFactory, genericTemplate },
@@ -173,11 +185,15 @@ public class RedisMapTests extends AbstractRedisMapTests<Object, Object> {
{ personFactory, stringFactory, genericTemplateLettuce },
{ personFactory, stringFactory, xGenericTemplateLettuce },
{ personFactory, stringFactory, jsonPersonTemplateLettuce },
{ stringFactory, doubleFactory, stringTemplateLtc},
{ stringFactory, longFactory, stringTemplateLtc},
{ stringFactory, stringFactory, genericTemplateSrp },
{ personFactory, personFactory, genericTemplateSrp },
{ stringFactory, personFactory, genericTemplateSrp },
{ personFactory, stringFactory, genericTemplateSrp },
{ personFactory, stringFactory, xGenericTemplateSrp },
{ stringFactory, doubleFactory, stringTemplateSrp},
{ stringFactory, longFactory, stringTemplateSrp},
{ personFactory, stringFactory, jsonPersonTemplateSrp }});
}
}

View File

@@ -41,6 +41,7 @@ import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.connection.jredis.DefaultJredisPool;
import org.springframework.data.redis.connection.jredis.JredisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.srp.SrpConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.JacksonJsonRedisSerializer;
@@ -235,6 +236,8 @@ public class RedisPropertiesTests extends RedisMapTests {
// create Jedis Factory
ObjectFactory<String> stringFactory = new StringObjectFactory();
ObjectFactory<String> longFactory = new LongObjectFactory();
ObjectFactory<String> doubleFactory = new DoubleObjectFactory();
JedisConnectionFactory jedisConnFactory = new JedisConnectionFactory();
jedisConnFactory.setUsePool(true);
@@ -296,9 +299,29 @@ public class RedisPropertiesTests extends RedisMapTests {
jsonPersonTemplateLtc.setHashValueSerializer(jsonStringSerializer);
jsonPersonTemplateLtc.afterPropertiesSet();
// SRP
SrpConnectionFactory srpConnFactory = new SrpConnectionFactory();
srpConnFactory.setPort(SettingsUtils.getPort());
srpConnFactory.setHostName(SettingsUtils.getHost());
srpConnFactory.afterPropertiesSet();
RedisTemplate<String, String> genericTemplateSrp = new StringRedisTemplate(srpConnFactory);
RedisTemplate<String, Person> xGenericTemplateSrp = new RedisTemplate<String, Person>();
xGenericTemplateSrp.setConnectionFactory(srpConnFactory);
xGenericTemplateSrp.setDefaultSerializer(serializer);
xGenericTemplateSrp.afterPropertiesSet();
RedisTemplate<String, Person> jsonPersonTemplateSrp = new RedisTemplate<String, Person>();
jsonPersonTemplateSrp.setConnectionFactory(srpConnFactory);
jsonPersonTemplateSrp.setDefaultSerializer(jsonSerializer);
jsonPersonTemplateSrp.setHashKeySerializer(jsonSerializer);
jsonPersonTemplateSrp.setHashValueSerializer(jsonStringSerializer);
jsonPersonTemplateSrp.afterPropertiesSet();
return Arrays.asList(new Object[][] { { stringFactory, stringFactory, genericTemplate },
{ stringFactory, stringFactory, genericTemplate }, { stringFactory, stringFactory, genericTemplate },
{ stringFactory, stringFactory, genericTemplate },
{ stringFactory, stringFactory, genericTemplate },
{ stringFactory, stringFactory, genericTemplate },
{ stringFactory, stringFactory, xstreamGenericTemplate },
{ stringFactory, stringFactory, genericTemplateJR },
@@ -312,7 +335,17 @@ public class RedisPropertiesTests extends RedisMapTests {
{ stringFactory, stringFactory, genericTemplateLtc },
{ stringFactory, stringFactory, genericTemplateLtc },
{ stringFactory, stringFactory, genericTemplateLtc },
{ stringFactory, doubleFactory, genericTemplateLtc },
{ stringFactory, longFactory, genericTemplateLtc },
{ stringFactory, stringFactory, xGenericTemplateLtc },
{ stringFactory, stringFactory, jsonPersonTemplateLtc }});
{ stringFactory, stringFactory, jsonPersonTemplateLtc },
{ stringFactory, stringFactory, genericTemplateSrp },
{ stringFactory, stringFactory, genericTemplateSrp },
{ stringFactory, stringFactory, genericTemplateSrp },
{ stringFactory, stringFactory, genericTemplateSrp },
{ stringFactory, doubleFactory, genericTemplateSrp },
{ stringFactory, longFactory, genericTemplateSrp },
{ stringFactory, stringFactory, xGenericTemplateSrp },
{ stringFactory, stringFactory, jsonPersonTemplateSrp }});
}
}