From 1ad4c1d72bf576f8f80224743e23b5f6dca19e84 Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Fri, 26 Nov 2010 19:49:30 +0200 Subject: [PATCH 1/3] + add getOperations to boundSet|List ops update DefaultRedisList to use a bound ops internally --- .../redis/core/BoundListOperations.java | 4 ++ .../redis/core/BoundSetOperations.java | 4 +- .../keyvalue/redis/core/ListOperations.java | 2 + .../keyvalue/redis/core/RedisTemplate.java | 7 ++- .../keyvalue/redis/util/DefaultRedisList.java | 49 ++++++++++++------- .../keyvalue/redis/util/DefaultRedisZSet.java | 2 +- 6 files changed, 45 insertions(+), 23 deletions(-) diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BoundListOperations.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BoundListOperations.java index f003e29e4..ebca7cc13 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BoundListOperations.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BoundListOperations.java @@ -24,6 +24,8 @@ import java.util.List; */ public interface BoundListOperations extends KeyBound { + RedisOperations getOperations(); + List range(int start, int end); void trim(int start, int end); @@ -41,4 +43,6 @@ public interface BoundListOperations extends KeyBound { Integer remove(int i, Object value); V index(int index); + + void set(int index, V value); } diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BoundSetOperations.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BoundSetOperations.java index f643e32d8..3a9ae4b07 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BoundSetOperations.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BoundSetOperations.java @@ -25,12 +25,12 @@ import java.util.Set; */ public interface BoundSetOperations extends KeyBound { + RedisOperations getOperations(); + Set diff(K... keys); void diffAndStore(K destKey, K... keys); - RedisOperations getOperations(); - Set intersect(K... keys); void intersectAndStore(K destKey, K... keys); diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/ListOperations.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/ListOperations.java index 29f0fd9b3..42e613bb2 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/ListOperations.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/ListOperations.java @@ -47,4 +47,6 @@ public interface ListOperations { List blockingLeftPop(int timeout, K... keys); List blockingRightPop(int timeout, K... keys); + + RedisOperations getOperations(); } 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 6506830c6..b232cbe9e 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 @@ -483,6 +483,11 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation } }, true); } + + @Override + public RedisOperations getOperations() { + return RedisTemplate.this; + } } // @@ -571,7 +576,7 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation public void intersectAndStore(K key, K destKey, K... keys) { final byte[][] rawKeys = rawKeys(aggregateKeys(key, keys)); final byte[] rawDestKey = rawKey(destKey); - Object rawValues = execute(new RedisCallback() { + execute(new RedisCallback() { @Override public Object doInRedis(RedisConnection connection) { connection.sInterStore(rawDestKey, rawKeys); diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/util/DefaultRedisList.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/util/DefaultRedisList.java index 8a453d62b..be73bc5e7 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/util/DefaultRedisList.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/util/DefaultRedisList.java @@ -21,7 +21,7 @@ import java.util.List; import java.util.ListIterator; import java.util.NoSuchElementException; -import org.springframework.data.keyvalue.redis.core.ListOperations; +import org.springframework.data.keyvalue.redis.core.BoundListOperations; import org.springframework.data.keyvalue.redis.core.RedisOperations; /** @@ -31,7 +31,7 @@ import org.springframework.data.keyvalue.redis.core.RedisOperations; */ public class DefaultRedisList extends AbstractRedisCollection implements RedisList { - private final ListOperations listOps; + private final BoundListOperations listOps; private class DefaultRedisListIterator extends RedisIterator { @@ -45,24 +45,35 @@ public class DefaultRedisList extends AbstractRedisCollection implements R } } + /** + * Constructs a new DefaultRedisList instance. + * + * @param key + * @param operations + */ public DefaultRedisList(String key, RedisOperations operations) { super(key, operations); - listOps = operations.listOps(); + listOps = operations.forList(key); + } + + public DefaultRedisList(BoundListOperations boundOps) { + super(boundOps.getKey(), boundOps.getOperations()); + listOps = boundOps; } @Override public List range(int start, int end) { - return listOps.range(key, start, end); + return listOps.range(start, end); } @Override public RedisList trim(int start, int end) { - listOps.trim(key, start, end); + listOps.trim(start, end); return this; } private List content() { - return listOps.range(key, 0, -1); + return listOps.range(0, -1); } @Override @@ -72,38 +83,38 @@ public class DefaultRedisList extends AbstractRedisCollection implements R @Override public int size() { - return listOps.length(key); + return listOps.length(); } @Override public boolean add(E value) { - listOps.rightPush(key, value); + listOps.rightPush(value); return true; } @Override public void clear() { - listOps.trim(key, size() + 1, 0); + listOps.trim(size() + 1, 0); } @Override public boolean remove(Object o) { - Integer result = listOps.remove(key, 0, o); + Integer result = listOps.remove(0, o); return (result != null && result.intValue() > 0); } @Override public void add(int index, E element) { if (index == 0) { - listOps.leftPush(key, element); + listOps.leftPush(element); return; } int size = size(); if (index == size()) { - listOps.rightPush(key, element); + listOps.rightPush(element); return; } @@ -121,7 +132,7 @@ public class DefaultRedisList extends AbstractRedisCollection implements R Collection reverseC = CollectionUtils.reverse(c); for (E e : reverseC) { - listOps.leftPush(key, e); + listOps.leftPush(e); } return true; } @@ -130,7 +141,7 @@ public class DefaultRedisList extends AbstractRedisCollection implements R if (index == size()) { for (E e : c) { - listOps.rightPush(key, e); + listOps.rightPush(e); } return true; } @@ -147,7 +158,7 @@ public class DefaultRedisList extends AbstractRedisCollection implements R if (index < 0 || index > size()) { throw new IndexOutOfBoundsException(); } - return listOps.index(key, index); + return listOps.index(index); } @Override @@ -179,7 +190,7 @@ public class DefaultRedisList extends AbstractRedisCollection implements R @Override public E set(int index, E e) { E object = get(index); - listOps.set(key, index, e); + listOps.set(index, e); return object; } @@ -201,21 +212,21 @@ public class DefaultRedisList extends AbstractRedisCollection implements R @Override public boolean offer(E e) { - listOps.leftPush(key, e); + listOps.leftPush(e); return true; } @Override public E peek() { - E element = listOps.index(key, 0); + E element = listOps.index(0); return (element == null ? null : element); } @Override public E poll() { - E element = listOps.leftPop(key); + E element = listOps.leftPop(); return (element == null ? null : element); } diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/util/DefaultRedisZSet.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/util/DefaultRedisZSet.java index f2ae67e9d..476e7daaf 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/util/DefaultRedisZSet.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/util/DefaultRedisZSet.java @@ -27,7 +27,7 @@ import org.springframework.data.keyvalue.redis.core.RedisOperations; * * @author Costin Leau */ -class DefaultRedisZSet extends AbstractRedisCollection implements RedisZSet { +public class DefaultRedisZSet extends AbstractRedisCollection implements RedisZSet { private final BoundZSetOperations boundZSetOps; private double defaultScore = 1; From 73ddd2637b096a573f4eb4f86bf6fd9a5e7e137c Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Fri, 26 Nov 2010 19:52:28 +0200 Subject: [PATCH 2/3] + introduce hash operations + introduce redis map implementation --- .../redis/core/BoundHashOperations.java | 24 ++++ .../core/DefaultBoundHashOperations.java | 33 +++++ .../core/DefaultBoundListOperations.java | 33 +++-- .../keyvalue/redis/core/HashOperations.java | 26 ++++ .../keyvalue/redis/core/RedisOperations.java | 4 + .../keyvalue/redis/core/RedisTemplate.java | 19 +++ .../keyvalue/redis/util/DefaultRedisMap.java | 121 ++++++++++++++++++ 7 files changed, 249 insertions(+), 11 deletions(-) create mode 100644 spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BoundHashOperations.java create mode 100644 spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundHashOperations.java create mode 100644 spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/HashOperations.java create mode 100644 spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/util/DefaultRedisMap.java 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 new file mode 100644 index 000000000..fe954333b --- /dev/null +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/BoundHashOperations.java @@ -0,0 +1,24 @@ +/* + * Copyright 2010 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; + +/** + * @author Costin Leau + */ +public interface BoundHashOperations extends KeyBound { + + +} 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 new file mode 100644 index 000000000..44a726fc7 --- /dev/null +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundHashOperations.java @@ -0,0 +1,33 @@ +/* + * Copyright 2010 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; + +/** + * Default implementation for {@link HashOperations}. + * + * @author Costin Leau + */ +class DefaultBoundHashOperations extends DefaultKeyBound implements BoundHashOperations { + + /** + * Constructs a new DefaultBoundHashOperations instance. + * + * @param key + */ + public DefaultBoundHashOperations(K key) { + super(key); + } +} diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundListOperations.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundListOperations.java index a2c576305..b2a413cc0 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundListOperations.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/DefaultBoundListOperations.java @@ -26,54 +26,65 @@ import java.util.List; public class DefaultBoundListOperations extends DefaultKeyBound implements BoundListOperations { private final ListOperations ops; - + public DefaultBoundListOperations(K key, RedisTemplate template) { super(key); this.ops = template.listOps(); } - + + + @Override + public RedisOperations getOperations() { + return ops.getOperations(); + } + @Override public V index(int index) { - throw new UnsupportedOperationException(); + return ops.index(getKey(), index); } @Override public V leftPop() { - throw new UnsupportedOperationException(); + return ops.leftPop(getKey()); } @Override public Integer leftPush(V value) { - throw new UnsupportedOperationException(); + return ops.leftPush(getKey(), value); } @Override public Integer length() { - throw new UnsupportedOperationException(); + return ops.length(getKey()); } @Override public List range(int start, int end) { - throw new UnsupportedOperationException(); + return ops.range(getKey(), start, end); } @Override public Integer remove(int i, Object value) { - throw new UnsupportedOperationException(); + return ops.remove(getKey(), i, value); } @Override public V rightPop() { - throw new UnsupportedOperationException(); + return ops.rightPop(getKey()); } @Override public Integer rightPush(V value) { - throw new UnsupportedOperationException(); + return ops.rightPush(getKey(), value); } @Override public void trim(int start, int end) { - throw new UnsupportedOperationException(); + ops.trim(getKey(), start, end); + } + + @Override + public void set(int index, V value) { + ops.set(getKey(), index, value); } } \ 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 new file mode 100644 index 000000000..865876da6 --- /dev/null +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/core/HashOperations.java @@ -0,0 +1,26 @@ +/* + * Copyright 2010 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; + +/** + * Redis map specific operations working on a hash. + * + * @author Costin Leau + */ +public interface HashOperations { + + +} 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 4aaa99039..06646c329 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 @@ -50,4 +50,8 @@ public interface RedisOperations { ZSetOperations zSetOps(); BoundZSetOperations forZSet(K key); + + HashOperations hashOps(); + + 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 b232cbe9e..5f82effc8 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 @@ -850,4 +850,23 @@ public class RedisTemplate extends RedisAccessor implements RedisOperation }, true); } } + + + // + // Hash Operations + // + + @Override + public BoundHashOperations forHash(K key) { + return new DefaultBoundHashOperations(key); + } + + @Override + public HashOperations hashOps() { + return new DefaultHashOperations(); + } + + private class DefaultHashOperations implements HashOperations { + + } } \ 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 new file mode 100644 index 000000000..8c304b0ca --- /dev/null +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/util/DefaultRedisMap.java @@ -0,0 +1,121 @@ +/* + * Copyright 2010 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.util; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +import org.springframework.data.keyvalue.redis.core.BoundHashOperations; +import org.springframework.data.keyvalue.redis.core.RedisOperations; + +/** + * Default implementation for {@link RedisMap}. + * + * @author Costin Leau + */ +public class DefaultRedisMap implements RedisMap { + + private final BoundHashOperations hashOps; + + public DefaultRedisMap(String key, RedisOperations operations) { + this.hashOps = operations.forHash(key); + } + + public DefaultRedisMap(BoundHashOperations boundOps) { + this.hashOps = boundOps; + } + + @Override + public Integer increment(K key, int delta) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean putIfAbsent(K key, V value) { + throw new UnsupportedOperationException(); + } + + @Override + public String getKey() { + throw new UnsupportedOperationException(); + } + + @Override + public RedisOperations getOperations() { + throw new UnsupportedOperationException(); + } + + @Override + public void clear() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean containsKey(Object key) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean containsValue(Object value) { + throw new UnsupportedOperationException(); + } + + @Override + public Set> entrySet() { + throw new UnsupportedOperationException(); + } + + @Override + public V get(Object key) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isEmpty() { + throw new UnsupportedOperationException(); + } + + @Override + public Set keySet() { + throw new UnsupportedOperationException(); + } + + @Override + public V put(K key, V value) { + throw new UnsupportedOperationException(); + } + + @Override + public void putAll(Map m) { + throw new UnsupportedOperationException(); + } + + @Override + public V remove(Object key) { + throw new UnsupportedOperationException(); + } + + @Override + public int size() { + throw new UnsupportedOperationException(); + } + + @Override + public Collection values() { + throw new UnsupportedOperationException(); + } +} \ No newline at end of file From fa31aa660ce575c880e3e7b4bbf94f6e3f2bf474 Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Fri, 26 Nov 2010 21:36:40 +0200 Subject: [PATCH 3/3] + 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