From fa31aa660ce575c880e3e7b4bbf94f6e3f2bf474 Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Fri, 26 Nov 2010 21:36:40 +0200 Subject: [PATCH] + finish bound hash operations + hash operations + finish hash ops implementations in RedisTemplate + finish redis map implementation --- .../redis/core/BoundHashOperations.java | 24 ++- .../core/DefaultBoundHashOperations.java | 65 +++++++- .../keyvalue/redis/core/HashOperations.java | 22 ++- .../keyvalue/redis/core/RedisOperations.java | 4 +- .../keyvalue/redis/core/RedisTemplate.java | 152 +++++++++++++++++- .../keyvalue/redis/util/DefaultRedisMap.java | 36 +++-- 6 files changed, 277 insertions(+), 26 deletions(-) diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BoundHashOperations.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BoundHashOperations.java index fe954333b..b0f71960d 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BoundHashOperations.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BoundHashOperations.java @@ -15,10 +15,32 @@ */ package org.springframework.data.keyvalue.redis.core; +import java.util.Collection; +import java.util.Map; +import java.util.Set; + /** * @author Costin Leau */ -public interface BoundHashOperations extends KeyBound { +public interface BoundHashOperations extends KeyBound { + RedisOperations getOperations(); + boolean hasKey(Object key); + + Integer increment(HK key, int delta); + + HV get(Object key); + + void set(HK key, HV value); + + void multiSet(Map m); + + Set keys(); + + Collection values(); + + Integer length(); + + void delete(Object key); } diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundHashOperations.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundHashOperations.java index 44a726fc7..7639ed704 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundHashOperations.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundHashOperations.java @@ -15,19 +15,78 @@ */ package org.springframework.data.keyvalue.redis.core; +import java.util.Collection; +import java.util.Map; +import java.util.Set; + /** * Default implementation for {@link HashOperations}. * * @author Costin Leau */ -class DefaultBoundHashOperations extends DefaultKeyBound implements BoundHashOperations { +class DefaultBoundHashOperations extends DefaultKeyBound implements BoundHashOperations { + + private final HashOperations ops; + private RedisOperations template; /** * Constructs a new DefaultBoundHashOperations instance. * * @param key + * @param template */ - public DefaultBoundHashOperations(K key) { + public DefaultBoundHashOperations(H key, RedisTemplate template) { super(key); + this.ops = template.hashOps(); } -} + + @Override + public void delete(Object key) { + ops.delete(getKey(), key); + } + + @Override + public HV get(Object key) { + return ops.get(getKey(), key); + } + + @Override + public RedisOperations getOperations() { + return template; + } + + @Override + public boolean hasKey(Object key) { + return ops.hasKey(getKey(), key); + } + + @Override + public Integer increment(HK key, int delta) { + return ops.increment(getKey(), key, delta); + } + + @Override + public Set keys() { + return ops.keys(getKey()); + } + + @Override + public Integer length() { + return ops.length(getKey()); + } + + @Override + public void multiSet(Map m) { + ops.multiSet(getKey(), m); + } + + @Override + public void set(HK key, HV value) { + ops.set(getKey(), key, value); + } + + @Override + public Collection values() { + return ops.values(getKey()); + } +} \ No newline at end of file diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/HashOperations.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/HashOperations.java index 865876da6..82618e745 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/HashOperations.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/HashOperations.java @@ -15,12 +15,32 @@ */ package org.springframework.data.keyvalue.redis.core; +import java.util.Collection; +import java.util.Map; +import java.util.Set; + /** * Redis map specific operations working on a hash. * * @author Costin Leau */ -public interface HashOperations { +public interface HashOperations { + void delete(H key, Object hashKey); + Boolean hasKey(H key, Object hashKey); + + HV get(H key, Object hashKey); + + Integer increment(H key, HK hashKey, int delta); + + Set keys(H key); + + Integer length(H key); + + void multiSet(H key, Map m); + + void set(H key, HK hashKey, HV value); + + Collection values(H key); } diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/RedisOperations.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/RedisOperations.java index 06646c329..5168bca7f 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/RedisOperations.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/RedisOperations.java @@ -51,7 +51,7 @@ public interface RedisOperations { BoundZSetOperations forZSet(K key); - HashOperations hashOps(); + HashOperations hashOps(); - BoundHashOperations forHash(K key); + BoundHashOperations forHash(K key); } 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 5f82effc8..01b7d0e70 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 @@ -21,8 +21,10 @@ import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.ArrayList; 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; @@ -211,6 +213,17 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation return (T) values; } + @SuppressWarnings("unchecked") + private Collection arbitraryValues(Collection rawValues, Class type) { + Collection values = (List.class.isAssignableFrom(type) ? new ArrayList(rawValues.size()) + : new LinkedHashSet(rawValues.size())); + for (byte[] bs : rawValues) { + values.add((H) valueSerializer.deserialize(bs)); + } + + return values; + } + // utility methods for the template internal methods private abstract class ValueDeserializingRedisCallback implements RedisCallback { private K key; @@ -857,16 +870,145 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation // @Override - public BoundHashOperations forHash(K key) { - return new DefaultBoundHashOperations(key); + public BoundHashOperations forHash(K key) { + return new DefaultBoundHashOperations(key, this); } @Override - public HashOperations hashOps() { - return new DefaultHashOperations(); + public HashOperations hashOps() { + return new DefaultHashOperations(); } - private class DefaultHashOperations implements HashOperations { + private class DefaultHashOperations implements HashOperations { + @Override + public HV get(K key, Object hashKey) { + final byte[] rawKey = rawKey(key); + final byte[] rawHashKey = rawValue(hashKey); + + byte[] rawHashValue = execute(new RedisCallback() { + @Override + public byte[] doInRedis(RedisConnection connection) { + return connection.hGet(rawKey, rawHashKey); + } + }, true); + + return (HV) valueSerializer.deserialize(rawHashValue); + } + + @Override + public Boolean hasKey(K key, Object hashKey) { + final byte[] rawKey = rawKey(key); + final byte[] rawHashKey = rawValue(hashKey); + + return execute(new RedisCallback() { + @Override + public Boolean doInRedis(RedisConnection connection) { + return connection.hExists(rawKey, rawHashKey); + } + }, true); + } + + @Override + public Integer increment(K key, HK hashKey, final int delta) { + final byte[] rawKey = rawKey(key); + final byte[] rawHashKey = rawValue(hashKey); + + return execute(new RedisCallback() { + @Override + public Integer doInRedis(RedisConnection connection) { + return connection.hIncrBy(rawKey, rawHashKey, delta); + } + }, true); + + } + + @Override + public Set keys(K key) { + final byte[] rawKey = rawKey(key); + + Set rawValues = execute(new RedisCallback>() { + @Override + public Set doInRedis(RedisConnection connection) { + return connection.hKeys(rawKey); + } + }, true); + + return (Set) arbitraryValues(rawValues, Set.class); + } + + @Override + public Integer length(K key) { + final byte[] rawKey = rawKey(key); + + return execute(new RedisCallback() { + @Override + public Integer doInRedis(RedisConnection connection) { + return connection.hLen(rawKey); + } + }, true); + } + + @Override + public void multiSet(K key, Map m) { + final byte[] rawKey = rawKey(key); + + final Map hashes = new LinkedHashMap(m.size()); + + for (Map.Entry entry : hashes.entrySet()) { + hashes.put(rawValue(entry.getKey()), rawValue(entry.getValue())); + } + + execute(new RedisCallback() { + @Override + public Object doInRedis(RedisConnection connection) { + connection.hMSet(rawKey, hashes); + return null; + } + }, true); + } + + @Override + public void set(K key, HK hashKey, HV value) { + final byte[] rawKey = rawKey(key); + final byte[] rawHashKey = rawValue(hashKey); + final byte[] rawHashValue = rawValue(value); + + execute(new RedisCallback() { + @Override + public Object doInRedis(RedisConnection connection) { + connection.hSet(rawKey, rawHashKey, rawHashValue); + return null; + } + }, true); + } + + @Override + public List values(K key) { + final byte[] rawKey = rawKey(key); + + List rawValues = execute(new RedisCallback>() { + @Override + public List doInRedis(RedisConnection connection) { + return connection.hVals(rawKey); + } + }, true); + + return (List) arbitraryValues(rawValues, List.class); + } + + @Override + public void delete(K key, Object hashKey) { + final byte[] rawKey = rawKey(key); + final byte[] rawHashKey = rawValue(hashKey); + + execute(new RedisCallback() { + @Override + public Object doInRedis(RedisConnection connection) { + connection.hDel(rawKey, rawHashKey); + return null; + } + }, true); + } } } \ No newline at end of file diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/util/DefaultRedisMap.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/util/DefaultRedisMap.java index 8c304b0ca..e1b3440ea 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/util/DefaultRedisMap.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/util/DefaultRedisMap.java @@ -41,32 +41,36 @@ public class DefaultRedisMap implements RedisMap { @Override public Integer increment(K key, int delta) { - throw new UnsupportedOperationException(); + return hashOps.increment(key, delta); } @Override public boolean putIfAbsent(K key, V value) { - throw new UnsupportedOperationException(); + if (!hashOps.hasKey(key)) { + put(key, value); + return true; + } + return false; } @Override public String getKey() { - throw new UnsupportedOperationException(); + return hashOps.getKey(); } @Override public RedisOperations getOperations() { - throw new UnsupportedOperationException(); + return hashOps.getOperations(); } @Override public void clear() { - throw new UnsupportedOperationException(); + getOperations().delete(getKey()); } @Override public boolean containsKey(Object key) { - throw new UnsupportedOperationException(); + return hashOps.hasKey(key); } @Override @@ -81,41 +85,45 @@ public class DefaultRedisMap implements RedisMap { @Override public V get(Object key) { - throw new UnsupportedOperationException(); + return hashOps.get(key); } @Override public boolean isEmpty() { - throw new UnsupportedOperationException(); + return size() == 0; } @Override public Set keySet() { - throw new UnsupportedOperationException(); + return hashOps.keys(); } @Override public V put(K key, V value) { - throw new UnsupportedOperationException(); + V oldV = get(key); + hashOps.set(key, value); + return oldV; } @Override public void putAll(Map m) { - throw new UnsupportedOperationException(); + hashOps.multiSet(m); } @Override public V remove(Object key) { - throw new UnsupportedOperationException(); + V v = get(key); + hashOps.delete(key); + return v; } @Override public int size() { - throw new UnsupportedOperationException(); + return hashOps.length(); } @Override public Collection values() { - throw new UnsupportedOperationException(); + return hashOps.values(); } } \ No newline at end of file