diff --git a/redisson/src/main/java/org/redisson/RedissonLocalCachedMap.java b/redisson/src/main/java/org/redisson/RedissonLocalCachedMap.java index f26ec693a..b7f192ece 100644 --- a/redisson/src/main/java/org/redisson/RedissonLocalCachedMap.java +++ b/redisson/src/main/java/org/redisson/RedissonLocalCachedMap.java @@ -43,7 +43,7 @@ import org.redisson.cache.Cache; import org.redisson.cache.LFUCacheMap; import org.redisson.cache.LRUCacheMap; import org.redisson.cache.NoneCacheMap; -import org.redisson.cache.SoftCacheMap; +import org.redisson.cache.ReferenceCacheMap; import org.redisson.client.codec.Codec; import org.redisson.client.codec.LongCodec; import org.redisson.client.codec.StringCodec; @@ -246,7 +246,10 @@ public class RedissonLocalCachedMap extends RedissonMap implements R return new LFUCacheMap(options.getCacheSize(), options.getTimeToLiveInMillis(), options.getMaxIdleInMillis()); } if (options.getEvictionPolicy() == EvictionPolicy.SOFT) { - return new SoftCacheMap(options.getTimeToLiveInMillis(), options.getMaxIdleInMillis()); + return ReferenceCacheMap.soft(options.getTimeToLiveInMillis(), options.getMaxIdleInMillis()); + } + if (options.getEvictionPolicy() == EvictionPolicy.WEAK) { + return ReferenceCacheMap.weak(options.getTimeToLiveInMillis(), options.getMaxIdleInMillis()); } throw new IllegalArgumentException("Invalid eviction policy: " + options.getEvictionPolicy()); } diff --git a/redisson/src/main/java/org/redisson/api/LocalCachedMapOptions.java b/redisson/src/main/java/org/redisson/api/LocalCachedMapOptions.java index 523cc5ff5..3977d8840 100644 --- a/redisson/src/main/java/org/redisson/api/LocalCachedMapOptions.java +++ b/redisson/src/main/java/org/redisson/api/LocalCachedMapOptions.java @@ -25,7 +25,7 @@ import java.util.concurrent.TimeUnit; */ public class LocalCachedMapOptions { - public enum EvictionPolicy {NONE, LRU, LFU, SOFT}; + public enum EvictionPolicy {NONE, LRU, LFU, SOFT, WEAK}; private boolean invalidateEntryOnChange; private EvictionPolicy evictionPolicy; diff --git a/redisson/src/main/java/org/redisson/cache/CachedValueReference.java b/redisson/src/main/java/org/redisson/cache/CachedValueSoftReference.java similarity index 78% rename from redisson/src/main/java/org/redisson/cache/CachedValueReference.java rename to redisson/src/main/java/org/redisson/cache/CachedValueSoftReference.java index c6e0c4bfb..b701e04b2 100644 --- a/redisson/src/main/java/org/redisson/cache/CachedValueReference.java +++ b/redisson/src/main/java/org/redisson/cache/CachedValueSoftReference.java @@ -18,11 +18,17 @@ package org.redisson.cache; import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; -public class CachedValueReference extends SoftReference { +/** + * + * @author Nikita Koksharov + * + * @param value type + */ +public class CachedValueSoftReference extends SoftReference { private final CachedValue owner; - public CachedValueReference(CachedValue owner, V referent, ReferenceQueue q) { + public CachedValueSoftReference(CachedValue owner, V referent, ReferenceQueue q) { super(referent, q); this.owner = owner; } diff --git a/redisson/src/main/java/org/redisson/cache/CachedValueWeakReference.java b/redisson/src/main/java/org/redisson/cache/CachedValueWeakReference.java new file mode 100644 index 000000000..65814615d --- /dev/null +++ b/redisson/src/main/java/org/redisson/cache/CachedValueWeakReference.java @@ -0,0 +1,40 @@ +/** + * Copyright 2016 Nikita Koksharov + * + * 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.redisson.cache; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; + +/** + * + * @author Nikita Koksharov + * + * @param value type + */ +public class CachedValueWeakReference extends WeakReference { + + private final CachedValue owner; + + public CachedValueWeakReference(CachedValue owner, V referent, ReferenceQueue q) { + super(referent, q); + this.owner = owner; + } + + public CachedValue getOwner() { + return owner; + } + +} diff --git a/redisson/src/main/java/org/redisson/cache/SoftCacheMap.java b/redisson/src/main/java/org/redisson/cache/ReferenceCacheMap.java similarity index 59% rename from redisson/src/main/java/org/redisson/cache/SoftCacheMap.java rename to redisson/src/main/java/org/redisson/cache/ReferenceCacheMap.java index d861fb37c..0f4493a24 100644 --- a/redisson/src/main/java/org/redisson/cache/SoftCacheMap.java +++ b/redisson/src/main/java/org/redisson/cache/ReferenceCacheMap.java @@ -17,6 +17,8 @@ package org.redisson.cache; import java.lang.ref.ReferenceQueue; +import org.redisson.cache.ReferenceCachedValue.Type; + /** * * @author Nikita Koksharov @@ -24,22 +26,33 @@ import java.lang.ref.ReferenceQueue; * @param key * @param value */ -public class SoftCacheMap extends AbstractCacheMap { +public class ReferenceCacheMap extends AbstractCacheMap { private final ReferenceQueue queue = new ReferenceQueue(); - public SoftCacheMap(long timeToLiveInMillis, long maxIdleInMillis) { + private ReferenceCachedValue.Type type; + + public static ReferenceCacheMap weak(long timeToLiveInMillis, long maxIdleInMillis) { + return new ReferenceCacheMap(timeToLiveInMillis, maxIdleInMillis, Type.WEAK); + } + + public static ReferenceCacheMap soft(long timeToLiveInMillis, long maxIdleInMillis) { + return new ReferenceCacheMap(timeToLiveInMillis, maxIdleInMillis, Type.SOFT); + } + + ReferenceCacheMap(long timeToLiveInMillis, long maxIdleInMillis, ReferenceCachedValue.Type type) { super(0, timeToLiveInMillis, maxIdleInMillis); + this.type = type; } protected CachedValue create(K key, V value, long ttl, long maxIdleTime) { - return new SoftCachedValue(key, value, ttl, maxIdleTime, queue); + return new ReferenceCachedValue(key, value, ttl, maxIdleTime, queue, type); } @Override protected boolean removeExpiredEntries() { while (true) { - CachedValueReference value = (CachedValueReference) queue.poll(); + CachedValueSoftReference value = (CachedValueSoftReference) queue.poll(); if (value == null) { break; } diff --git a/redisson/src/main/java/org/redisson/cache/SoftCachedValue.java b/redisson/src/main/java/org/redisson/cache/ReferenceCachedValue.java similarity index 61% rename from redisson/src/main/java/org/redisson/cache/SoftCachedValue.java rename to redisson/src/main/java/org/redisson/cache/ReferenceCachedValue.java index efdedc100..ed59f20c7 100644 --- a/redisson/src/main/java/org/redisson/cache/SoftCachedValue.java +++ b/redisson/src/main/java/org/redisson/cache/ReferenceCachedValue.java @@ -15,19 +15,26 @@ */ package org.redisson.cache; +import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; /** * Created by jribble on 2/20/17. */ -public class SoftCachedValue extends StdCachedValue implements CachedValue { +public class ReferenceCachedValue extends StdCachedValue implements CachedValue { - private final CachedValueReference ref; + public enum Type {SOFT, WEAK} + + private final Reference ref; - public SoftCachedValue(K key, V value, long ttl, long maxIdleTime, ReferenceQueue queue) { + public ReferenceCachedValue(K key, V value, long ttl, long maxIdleTime, ReferenceQueue queue, Type type) { super(key, null, ttl, maxIdleTime); - this.ref = new CachedValueReference(this, value, queue); + if (type == Type.SOFT) { + this.ref = new CachedValueSoftReference(this, value, queue); + } else { + this.ref = new CachedValueWeakReference(this, value, queue); + } } @Override diff --git a/redisson/src/test/java/org/redisson/misc/SoftCacheMapTest.java b/redisson/src/test/java/org/redisson/misc/SoftCacheMapTest.java index dd074932e..69642660f 100644 --- a/redisson/src/test/java/org/redisson/misc/SoftCacheMapTest.java +++ b/redisson/src/test/java/org/redisson/misc/SoftCacheMapTest.java @@ -2,7 +2,7 @@ package org.redisson.misc; import org.junit.Test; import org.redisson.cache.Cache; -import org.redisson.cache.SoftCacheMap; +import org.redisson.cache.ReferenceCacheMap; import java.util.Objects; import java.util.concurrent.TimeUnit; @@ -13,7 +13,7 @@ public class SoftCacheMapTest { @Test public void testMaxIdleTimeEviction() throws InterruptedException { - Cache map = new SoftCacheMap(0, 0); + Cache map = ReferenceCacheMap.soft(0, 0); map.put(1, 0, 0, TimeUnit.MILLISECONDS, 400, TimeUnit.MILLISECONDS); assertThat(map.get(1)).isEqualTo(0); Thread.sleep(200); @@ -28,7 +28,7 @@ public class SoftCacheMapTest { @Test public void testTTLEviction() throws InterruptedException { - Cache map = new SoftCacheMap(0, 0); + Cache map = ReferenceCacheMap.soft(0, 0); map.put(1, 0, 500, TimeUnit.MILLISECONDS, 0, TimeUnit.MILLISECONDS); assertThat(map.get(1)).isEqualTo(0); Thread.sleep(100); @@ -40,7 +40,7 @@ public class SoftCacheMapTest { @Test public void testSizeEviction() { - Cache map = new SoftCacheMap(0, 0); + Cache map = ReferenceCacheMap.soft(0, 0); map.put(1, 0); map.put(2, 0); @@ -54,7 +54,7 @@ public class SoftCacheMapTest { // This test requires using -XX:SoftRefLRUPolicyMSPerMB=0 to pass @Test public void testSoftReferences() { - Cache map = new SoftCacheMap(0, 0); + Cache map = ReferenceCacheMap.soft(0, 0); for(int i=0;i<100000;i++) { map.put(i, new Integer(i)); }