WEAK eviction policy added for RedissonLocalCachedMap

pull/857/head
Nikita 8 years ago
parent a91d54227d
commit bac2e9becd

@ -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<K, V> extends RedissonMap<K, V> implements R
return new LFUCacheMap<CacheKey, CacheValue>(options.getCacheSize(), options.getTimeToLiveInMillis(), options.getMaxIdleInMillis());
}
if (options.getEvictionPolicy() == EvictionPolicy.SOFT) {
return new SoftCacheMap<CacheKey, CacheValue>(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());
}

@ -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;

@ -18,11 +18,17 @@ package org.redisson.cache;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
public class CachedValueReference<V> extends SoftReference<V> {
/**
*
* @author Nikita Koksharov
*
* @param <V> value type
*/
public class CachedValueSoftReference<V> extends SoftReference<V> {
private final CachedValue<?, ?> owner;
public CachedValueReference(CachedValue<?, ?> owner, V referent, ReferenceQueue<? super V> q) {
public CachedValueSoftReference(CachedValue<?, ?> owner, V referent, ReferenceQueue<? super V> q) {
super(referent, q);
this.owner = owner;
}

@ -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 <V> value type
*/
public class CachedValueWeakReference<V> extends WeakReference<V> {
private final CachedValue<?, ?> owner;
public CachedValueWeakReference(CachedValue<?, ?> owner, V referent, ReferenceQueue<? super V> q) {
super(referent, q);
this.owner = owner;
}
public CachedValue<?, ?> getOwner() {
return owner;
}
}

@ -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 <K> key
* @param <V> value
*/
public class SoftCacheMap<K, V> extends AbstractCacheMap<K, V> {
public class ReferenceCacheMap<K, V> extends AbstractCacheMap<K, V> {
private final ReferenceQueue<V> queue = new ReferenceQueue<V>();
public SoftCacheMap(long timeToLiveInMillis, long maxIdleInMillis) {
private ReferenceCachedValue.Type type;
public static <K, V> ReferenceCacheMap<K, V> weak(long timeToLiveInMillis, long maxIdleInMillis) {
return new ReferenceCacheMap<K, V>(timeToLiveInMillis, maxIdleInMillis, Type.WEAK);
}
public static <K, V> ReferenceCacheMap<K, V> soft(long timeToLiveInMillis, long maxIdleInMillis) {
return new ReferenceCacheMap<K, V>(timeToLiveInMillis, maxIdleInMillis, Type.SOFT);
}
ReferenceCacheMap(long timeToLiveInMillis, long maxIdleInMillis, ReferenceCachedValue.Type type) {
super(0, timeToLiveInMillis, maxIdleInMillis);
this.type = type;
}
protected CachedValue<K, V> create(K key, V value, long ttl, long maxIdleTime) {
return new SoftCachedValue<K, V>(key, value, ttl, maxIdleTime, queue);
return new ReferenceCachedValue<K, V>(key, value, ttl, maxIdleTime, queue, type);
}
@Override
protected boolean removeExpiredEntries() {
while (true) {
CachedValueReference<V> value = (CachedValueReference<V>) queue.poll();
CachedValueSoftReference<V> value = (CachedValueSoftReference<V>) queue.poll();
if (value == null) {
break;
}

@ -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<K, V> extends StdCachedValue<K, V> implements CachedValue<K, V> {
public class ReferenceCachedValue<K, V> extends StdCachedValue<K, V> implements CachedValue<K, V> {
private final CachedValueReference<V> ref;
public enum Type {SOFT, WEAK}
private final Reference<V> ref;
public SoftCachedValue(K key, V value, long ttl, long maxIdleTime, ReferenceQueue<V> queue) {
public ReferenceCachedValue(K key, V value, long ttl, long maxIdleTime, ReferenceQueue<V> queue, Type type) {
super(key, null, ttl, maxIdleTime);
this.ref = new CachedValueReference<V>(this, value, queue);
if (type == Type.SOFT) {
this.ref = new CachedValueSoftReference<V>(this, value, queue);
} else {
this.ref = new CachedValueWeakReference<V>(this, value, queue);
}
}
@Override

@ -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<Integer, Integer> map = new SoftCacheMap<Integer, Integer>(0, 0);
Cache<Integer, Integer> 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<Integer, Integer> map = new SoftCacheMap<Integer, Integer>(0, 0);
Cache<Integer, Integer> 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<Integer, Integer> map = new SoftCacheMap<Integer, Integer>(0, 0);
Cache<Integer, Integer> 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<Integer, Integer> map = new SoftCacheMap<Integer, Integer>(0, 0);
Cache<Integer, Integer> map = ReferenceCacheMap.soft(0, 0);
for(int i=0;i<100000;i++) {
map.put(i, new Integer(i));
}

Loading…
Cancel
Save