
com.alicp.jetcache.embedded.LinkedHashMapCache Maven / Gradle / Ivy
The newest version!
/**
* Created on 13-09-12 19:02
*/
package com.alicp.jetcache.embedded;
import com.alicp.jetcache.CacheResultCode;
import com.alicp.jetcache.CacheValueHolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author huangli
*/
public class LinkedHashMapCache extends AbstractEmbeddedCache {
private static Logger logger = LoggerFactory.getLogger(LinkedHashMapCache.class);
public LinkedHashMapCache(EmbeddedCacheConfig config) {
super(config);
addToCleaner();
}
protected void addToCleaner() {
Cleaner.add(this);
}
@Override
protected InnerMap createAreaCache() {
return new LRUMap(config.getLimit());
}
@Override
public T unwrap(Class clazz) {
if (clazz.equals(LinkedHashMap.class)) {
return (T) innerMap;
}
throw new IllegalArgumentException(clazz.getName());
}
public void cleanExpiredEntry() {
((LRUMap) innerMap).cleanExpiredEntry();
}
final class LRUMap extends LinkedHashMap implements InnerMap {
private final int max;
private final ReentrantLock lock = new ReentrantLock();
public LRUMap(int max) {
super((int) (max * 1.4f), 0.75f, true);
this.max = max;
// this.lockObj = lockObj;
}
@Override
protected boolean removeEldestEntry(Map.Entry eldest) {
return size() > max;
}
void cleanExpiredEntry() {
lock.lock();
long t = System.currentTimeMillis();
try {
for (Iterator it = entrySet().iterator(); it.hasNext(); ) {
Map.Entry en = (Map.Entry) it.next();
Object value = en.getValue();
if (value != null) {
CacheValueHolder h;
try {
h = (CacheValueHolder) value;
} catch (ClassCastException e) {
// assert false
logger.error("value of key " + en.getKey() + " is not a CacheValueHolder. type=" + value.getClass());
it.remove();
continue;
}
if (t >= h.getExpireTime()) {
it.remove();
}
} else {
// assert false
logger.error("key " + en.getKey() + " is null");
}
}
} finally {
lock.unlock();
}
}
@Override
public Object getValue(Object key) {
lock.lock();
try{
return get(key);
}finally {
lock.unlock();
}
}
@Override
public Map getAllValues(Collection keys) {
lock.lock();
Map values = new HashMap();
try{
for (Object key : keys) {
Object v = get(key);
if (v != null) {
values.put(key, v);
}
}
}finally {
lock.unlock();
}
return values;
}
@Override
public void putValue(Object key, Object value) {
lock.lock();
try{
put(key, value);
}finally {
lock.unlock();
}
}
@Override
public void putAllValues(Map map) {
lock.lock();
try{
Set set = map.entrySet();
for (Map.Entry en : set) {
put(en.getKey(), en.getValue());
}
}finally {
lock.unlock();
}
}
@Override
public boolean removeValue(Object key) {
lock.lock();
try{
return remove(key) != null;
}finally {
lock.unlock();
}
}
@Override
public void removeAllValues(Collection keys) {
lock.lock();
try{
for (Object k : keys) {
remove(k);
}
}finally {
lock.unlock();
}
}
@Override
@SuppressWarnings("unchecked")
public boolean putIfAbsentValue(Object key, Object value) {
lock.lock();
try{
CacheValueHolder h = (CacheValueHolder) get(key);
if (h == null || parseHolderResult(h).getResultCode() == CacheResultCode.EXPIRED) {
put(key, value);
return true;
} else {
return false;
}
}finally {
lock.unlock();
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy