From 60bca9e549b7c2a0fb4977ccc2e515a7bee13455 Mon Sep 17 00:00:00 2001 From: Costin Leau Date: Wed, 13 Jul 2011 16:18:07 +0300 Subject: [PATCH] + update Spring's Cache abstraction to Spring 3.1 M2 --- pom.xml | 2 +- .../data/gemfire/support/GemfireCache.java | 144 +++--------------- .../gemfire/support/GemfireCacheManager.java | 14 +- .../support/AbstractNativeCacheTest.java | 72 --------- .../gemfire/support/GemfireCacheTest.java | 2 +- 5 files changed, 26 insertions(+), 208 deletions(-) diff --git a/pom.xml b/pom.xml index 03a4a8cb..5e713d36 100644 --- a/pom.xml +++ b/pom.xml @@ -59,7 +59,7 @@ limitations under the License. - 3.1.0.M1 + 3.1.0.M2 4.7 diff --git a/src/main/java/org/springframework/data/gemfire/support/GemfireCache.java b/src/main/java/org/springframework/data/gemfire/support/GemfireCache.java index b2b4d627..bb3a80d4 100644 --- a/src/main/java/org/springframework/data/gemfire/support/GemfireCache.java +++ b/src/main/java/org/springframework/data/gemfire/support/GemfireCache.java @@ -16,165 +16,55 @@ package org.springframework.data.gemfire.support; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.Condition; -import java.util.concurrent.locks.Lock; +import org.springframework.cache.Cache; +import org.springframework.cache.interceptor.DefaultValueWrapper; -import org.springframework.cache.support.AbstractDelegatingCache; - -import com.gemstone.gemfire.cache.DataPolicy; import com.gemstone.gemfire.cache.GemFireCache; import com.gemstone.gemfire.cache.Region; /** * Spring Framework {@link Cache} implementation using a GemFire {@link Region} underneath. - * Supports both Gemfire 6.5 and 6.0. + * Supports Gemfire 6.5 or higher. * * @author Costin Leau */ -public class GemfireCache extends AbstractDelegatingCache { +public class GemfireCache implements Cache { - private static class NoOpLock implements Lock { - - public void lock() { - } - - public void lockInterruptibly() throws InterruptedException { - } - - public Condition newCondition() { - return null; - } - - public boolean tryLock() { - return false; - } - - public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { - return false; - } - - public void unlock() { - } - }; - - private static final Lock NO_OP_LOCK = new NoOpLock(); - - private static final boolean hasConcurrentMap = ConcurrentMap.class.isAssignableFrom(Region.class); - private final Region region; - private final boolean canUseLock; - private final boolean canUseConcurrentMap; + @SuppressWarnings("unchecked") + private final Region region; /** * Creates a {@link GemFireCache} instance. * * @param region backing GemFire region */ - public GemfireCache(Region region) { - super(region); + public GemfireCache(Region region) { this.region = region; - this.canUseLock = region.getAttributes().getScope().isGlobal(); - DataPolicy dataPolicy = region.getAttributes().getDataPolicy(); - this.canUseConcurrentMap = (hasConcurrentMap && (!dataPolicy.isNormal() && !dataPolicy.isEmpty())); } public String getName() { return region.getName(); } - public Region getNativeCache() { + public Region getNativeCache() { return region; } - public V putIfAbsent(K key, V value) { - if (canUseConcurrentMap) { - return region.putIfAbsent(key, value); - } - - // fall back to pre 6.5 API - Lock lock = (canUseLock ? region.getDistributedLock(key) : NO_OP_LOCK); - try { - lock.lock(); - if (!region.containsKey(key)) { - return region.put(key, value); - } - else { - return region.get(key); - } - } finally { - lock.unlock(); - } + public void clear() { + region.clear(); } - @SuppressWarnings("unchecked") - public boolean remove(Object key, Object value) { - if (canUseConcurrentMap) { - return region.remove(key, value); - } - - // fall back to pre 6.5 API - if (region.containsKey(key)) { - Lock lock = (canUseLock ? region.getDistributedLock((K) key) : NO_OP_LOCK); - try { - lock.lock(); - - if (region.get(key).equals(value)) { - region.remove(key); - return true; - } - } finally { - lock.unlock(); - } - } - return false; + public void evict(Object key) { + region.destroy(key); } - public boolean replace(K key, V oldValue, V newValue) { - if (canUseConcurrentMap) { - return region.replace(key, oldValue, newValue); - } + public ValueWrapper get(Object key) { + Object value = region.get(key); - if (region.containsKey(key)) { - // fall back to pre 6.5 API - Lock lock = (canUseLock ? region.getDistributedLock(key) : NO_OP_LOCK); - - try { - lock.lock(); - - if (region.get(key).equals(oldValue)) { - region.put(key, newValue); - return true; - } - else { - return false; - } - } finally { - lock.unlock(); - } - } - return false; + return (value == null ? null : new DefaultValueWrapper(value)); } - public V replace(K key, V value) { - if (canUseConcurrentMap) { - return region.replace(key, value); - } - - // fall back to pre 6.5 API - Lock lock = (canUseLock ? region.getDistributedLock(key) : NO_OP_LOCK); - - try { - lock.lock(); - - if (region.containsKey(key)) { - return region.put(key, value); - } - else { - return null; - } - } finally { - lock.unlock(); - } + public void put(Object key, Object value) { + region.put(key, value); } } \ No newline at end of file diff --git a/src/main/java/org/springframework/data/gemfire/support/GemfireCacheManager.java b/src/main/java/org/springframework/data/gemfire/support/GemfireCacheManager.java index 4aae64ca..58e4e482 100644 --- a/src/main/java/org/springframework/data/gemfire/support/GemfireCacheManager.java +++ b/src/main/java/org/springframework/data/gemfire/support/GemfireCacheManager.java @@ -33,19 +33,17 @@ import com.gemstone.gemfire.cache.Region; * * @author Costin Leau */ -@SuppressWarnings("unchecked") public class GemfireCacheManager extends AbstractCacheManager { private com.gemstone.gemfire.cache.Cache gemfireCache; - @Override - protected Collection> loadCaches() { + protected Collection loadCaches() { Assert.notNull(gemfireCache, "a backing GemFire cache is required"); Assert.isTrue(!gemfireCache.isClosed(), "the GemFire cache is closed; an open instance is required"); Set> regions = gemfireCache.rootRegions(); - Collection> caches = new LinkedHashSet>(regions.size()); + Collection caches = new LinkedHashSet(regions.size()); for (Region region : regions) { caches.add(new GemfireCache(region)); @@ -54,13 +52,15 @@ public class GemfireCacheManager extends AbstractCacheManager { return caches; } - public Cache getCache(String name) { - Cache cache = super.getCache(name); + @Override + public Cache getCache(String name) { + Cache cache = super.getCache(name); + if (cache == null) { // check the gemfire cache again // in case the cache was added at runtime - Region reg = gemfireCache.getRegion(name); + Region reg = gemfireCache.getRegion(name); if (reg != null) { cache = new GemfireCache(reg); getCacheMap().put(name, cache); diff --git a/src/test/java/org/springframework/data/gemfire/support/AbstractNativeCacheTest.java b/src/test/java/org/springframework/data/gemfire/support/AbstractNativeCacheTest.java index d8f863d6..49d043cc 100644 --- a/src/test/java/org/springframework/data/gemfire/support/AbstractNativeCacheTest.java +++ b/src/test/java/org/springframework/data/gemfire/support/AbstractNativeCacheTest.java @@ -69,17 +69,6 @@ public abstract class AbstractNativeCacheTest { assertEquals(value, cache.get(key)); } - @Test - public void testCacheRemove() throws Exception { - Object key = "enescu"; - Object value = "george"; - - assertNull(cache.get(key)); - cache.put(key, value); - assertEquals(value, cache.remove(key)); - assertNull(cache.get(key)); - } - @Test public void testCacheClear() throws Exception { assertNull(cache.get("enescu")); @@ -91,65 +80,4 @@ public abstract class AbstractNativeCacheTest { assertNull(cache.get("enescu")); } - // concurrent map tests - @Test - public void testPutIfAbsent() throws Exception { - Object key = "enescu"; - Object value1 = "george"; - Object value2 = "geo"; - - assertNull(cache.get("enescu")); - cache.put(key, value1); - cache.putIfAbsent(key, value2); - assertEquals(value1, cache.get(key)); - } - - @Test - public void testConcurrentRemove() throws Exception { - Object key = "enescu"; - Object value1 = "george"; - Object value2 = "geo"; - - assertNull(cache.get("enescu")); - cache.put(key, value1); - // no remove - cache.remove(key, value2); - assertEquals(value1, cache.get(key)); - // one remove - cache.remove(key, value1); - assertNull(cache.get("enescu")); - } - - @Test - public void testConcurrentReplace() throws Exception { - Object key = "enescu"; - Object value1 = "george"; - Object value2 = "geo"; - - assertNull(cache.get("enescu")); - cache.put(key, value1); - cache.replace(key, value2); - assertEquals(value2, cache.get(key)); - cache.remove(key); - cache.replace(key, value1); - assertNull(cache.get("enescu")); - } - - @Test - public void testConcurrentReplaceIfEqual() throws Exception { - Object key = "enescu"; - Object value1 = "george"; - Object value2 = "geo"; - - assertNull(cache.get("enescu")); - cache.put(key, value1); - assertEquals(value1, cache.get(key)); - // no replace - cache.replace(key, value2, value1); - assertEquals(value1, cache.get(key)); - cache.replace(key, value1, value2); - assertEquals(value2, cache.get(key)); - cache.replace(key, value2, value1); - assertEquals(value1, cache.get(key)); - } } \ No newline at end of file diff --git a/src/test/java/org/springframework/data/gemfire/support/GemfireCacheTest.java b/src/test/java/org/springframework/data/gemfire/support/GemfireCacheTest.java index 1180348a..01694b3c 100644 --- a/src/test/java/org/springframework/data/gemfire/support/GemfireCacheTest.java +++ b/src/test/java/org/springframework/data/gemfire/support/GemfireCacheTest.java @@ -32,7 +32,7 @@ public class GemfireCacheTest extends AbstractNativeCacheTest nativeCache) { - return new GemfireCache(nativeCache); + return new GemfireCache(nativeCache); } @Override